Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Error Tracking: Allow custom error reporting logic to be called in Error Boundaries via a WP action hook #42024

Merged
merged 6 commits into from
Jul 12, 2022

Conversation

fullofcaffeine
Copy link
Member

@fullofcaffeine fullofcaffeine commented Jun 28, 2022

What?

Create an extension point in Gutenberg Error Boundaries that allows any client code (browser JS code running in the same context as the GB editor) to call custom logic as part of the boundaries' componentDidCatch methods, via a WP action hook. This logic can be set by any JS code running in the same context as the Gutenberg plugin that has access to import and use addAction from the @wordpress/hooks package.

Why?

Error Boundaries provide a great way to customize the way rendering errors are caught and presented to the user, however, they end up swallowing the errors. This means that if you want to report it somewhere else, you're out of luck (as in, you need to modify the actual GB source code).

A typical real-world scenario is the use of tools like Sentry or Rollbar. By default, these tools setup a global error handler that will track and capture any uncaught error that ends up bubbling up to it. This is not the case for errors handled by React Error Boundaries, so they end up not being captured at all.

These tools usually provide their own Error Boundaries that will take care of capturing the errors, but Gutenberg already has many Error Boundaries with their custom logic, and we're not looking to replace them. We also don't want to couple the custom error reporting logic to the Error Boundary classes, either. We want them to be optional and set by any other JS code running in the same context (any other plugin/mu-plugin or enqueued js file).

How?

For each React Error Boundary in Gutenberg, as part of the componentDidCall callback, we introduce a new gb.reportErrorBoundaryException action hook call (the name is provisory and up for discussion) and pass the error as its payload:

class ErrorBoundary extends Component {
	componentDidCatch( error ) {
		this.setState( { error } );

		doAction( 'gb.reportErrorBoundaryException', error );
	}
}

Then, in any client JS code - which could be, say, the logic that sets up a tool like Sentry or Rollbar - we can then do something like:

Sentry.init( {
	dsn: 'https://<dsn>',
} );

addAction( 'gb.reportErrorBoundaryException', 'mu-plugin/sentry-setup', ( error ) => {
	Sentry.reportError( error );
} );

TODO

  • Discuss the approach :)
  • Add unit-tests
  • Add manual testing instructions
  • Should we worry about multiple addAction calls setting multiple callbacks? (I think not)
  • Any security concerns?

Testing Instructions

1) In your WP test instance, add a wp-content/mu-plugins/test.php file with the following contents:

<?php
function testit() {
    wp_register_script('test', '');
    wp_enqueue_script('test' );
    wp_add_inline_script('test', "wp.hooks.addAction('gb.reportErrorBoundaryException', 'testing', (error) => {
       console.error('Opsie!', error);
    });");
}

add_action( 'admin_enqueue_scripts', 'testit', 99 );

2) Force an error in a component that's wrapped by one of the available React Error Boundaries. Here's a diff for the PostTitle component, which will test the Error Boundary in packages/editor/src/components/error-boundary:

diff --git i/packages/editor/src/components/post-title/index.js w/packages/editor/src/components/post-title/index.js
index 6930819700..19bb9b9a72 100644
--- i/packages/editor/src/components/post-title/index.js
+++ w/packages/editor/src/components/post-title/index.js
@@ -208,6 +208,7 @@ function PostTitle( _, forwardedRef ) {
                                ref={ useMergeRefs( [ richTextRef, ref ] ) }
                                contentEditable
                                className={ className }
+                               foo={ bar }
                                aria-label={ decodedPlaceholder }
                                role="textbox"
                                aria-multiline="true"

Apply this diff to your custom build of GB based on this branch. Make sure it's installed and active in your WP test instance.

3) Start a new post. You'll see the The editor has encountered an unexpected error. warning message, and if you open the console, you should see the error log prefixed with Opsie, meaning the custom action callback you setup in step 1) ran successfully.

Resolves: #41094

@github-actions
Copy link

github-actions bot commented Jun 28, 2022

Size Change: +696 B (0%)

Total Size: 1.25 MB

Filename Size Change
build/block-editor/index.min.js 152 kB +132 B (0%)
build/block-editor/style-rtl.css 14.6 kB +79 B (+1%)
build/block-editor/style.css 14.6 kB +84 B (+1%)
build/block-library/blocks/navigation-submenu/view.min.js 423 B +21 B (+5%) 🔍
build/block-library/blocks/navigation/view.min.js 443 B +20 B (+5%) 🔍
build/block-library/index.min.js 183 kB +43 B (0%)
build/blocks/index.min.js 47 kB +3 B (0%)
build/components/index.min.js 230 kB -6 B (0%)
build/customize-widgets/index.min.js 11.2 kB +25 B (0%)
build/edit-post/index.min.js 30.4 kB +1 B (0%)
build/edit-site/index.min.js 52.3 kB +238 B (0%)
build/edit-site/style-rtl.css 8.23 kB +2 B (0%)
build/edit-site/style.css 8.22 kB +4 B (0%)
build/edit-widgets/index.min.js 16.5 kB +30 B (0%)
build/editor/index.min.js 39.4 kB +23 B (0%)
build/list-reusable-blocks/index.min.js 1.74 kB -1 B (0%)
build/redux-routine/index.min.js 2.68 kB -2 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 6.58 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 103 B
build/block-library/blocks/audio/style.css 103 B
build/block-library/blocks/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 543 B
build/block-library/blocks/button/style.css 543 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 187 B
build/block-library/blocks/comment-template/style.css 185 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 95 B
build/block-library/blocks/comments/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 110 B
build/block-library/blocks/embed/theme.css 110 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.5 kB
build/block-library/blocks/gallery/style.css 1.49 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 333 B
build/block-library/blocks/group/editor.css 333 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 738 B
build/block-library/blocks/image/editor.css 737 B
build/block-library/blocks/image/style-rtl.css 524 B
build/block-library/blocks/image/style.css 530 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 705 B
build/block-library/blocks/navigation-link/editor.css 703 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.96 kB
build/block-library/blocks/navigation/style.css 1.95 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 495 B
build/block-library/blocks/post-comments-form/style.css 495 B
build/block-library/blocks/post-comments/editor-rtl.css 77 B
build/block-library/blocks/post-comments/editor.css 77 B
build/block-library/blocks/post-comments/style-rtl.css 632 B
build/block-library/blocks/post-comments/style.css 630 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 605 B
build/block-library/blocks/post-featured-image/editor.css 605 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 365 B
build/block-library/blocks/query/editor.css 364 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 385 B
build/block-library/blocks/search/style.css 386 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 708 B
build/block-library/blocks/site-logo/editor.css 708 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 159 B
build/block-library/blocks/video/style.css 159 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 987 B
build/block-library/common.css 984 B
build/block-library/editor-rtl.css 10.2 kB
build/block-library/editor.css 10.2 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.5 kB
build/block-library/style.css 11.5 kB
build/block-library/theme-rtl.css 695 B
build/block-library/theme.css 700 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/components/style-rtl.css 14 kB
build/components/style.css 14 kB
build/compose/index.min.js 11.7 kB
build/core-data/index.min.js 14.7 kB
build/customize-widgets/style-rtl.css 1.4 kB
build/customize-widgets/style.css 1.4 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 7.95 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.66 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4.02 kB
build/edit-navigation/style.css 4.03 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/style-rtl.css 6.97 kB
build/edit-post/style.css 6.97 kB
build/edit-widgets/style-rtl.css 4.35 kB
build/edit-widgets/style.css 4.35 kB
build/editor/style-rtl.css 3.65 kB
build/editor/style.css 3.65 kB
build/element/index.min.js 4.27 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.75 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.38 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 953 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.53 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 268 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice start, I think we only need to figure out how to address the concern you raised in https://github.com/WordPress/gutenberg/pull/42024/files#r909107114. Otherwise, it's all about documenting this new functionality so people can learn about it.

Any security concerns?

Great question. We will have to examine what exactly componenDidCatch exposes in error and info params.

Should we worry about multiple addAction calls setting multiple callbacks? (I think not)

Do you mean that the same callback can be registered multiple times if the app doesn't guard it? Can you explain what case are you worried about?

Totally optional for the first version. The fun part is that ErrorBoundry is the only React component that isn't using the functional form which became unusual in the world of hooks. I would be curious to check if we could abstract it also in a way so we don't have to use the extends syntax. There is a good article that covers it:
https://blog.logrocket.com/react-error-handling-react-error-boundary/. I'm definitely NOT advocating for using a library presented in the article, but maybe we can borrow some pattern that abstracts all that in a nice fashion.

@gziolo gziolo added Developer Experience Ideas about improving block and theme developer experience [Type] New API New API to be used by plugin developers or package users. [Feature] Extensibility The ability to extend blocks or the editing experience labels Jun 29, 2022
@fullofcaffeine
Copy link
Member Author

Totally optional for the first version. The fun part is that ErrorBoundry is the only React component that isn't using the functional form which became unusual in the world of hooks. I would be curious to check if we could abstract it also in a way so we don't have to use the extends syntax. There is a good article that covers it:
https://blog.logrocket.com/react-error-handling-react-error-boundary/. I'm definitely NOT advocating for using a library presented in the article, but maybe we can borrow some pattern that abstracts all that in a nice fashion.

Ah, just saw this after I replied here. Thanks for the pointer. I'm definitely interested in working on that as a follow-up!

@fullofcaffeine
Copy link
Member Author

Do you mean that the same callback can be registered multiple times if the app doesn't guard it? Can you explain what case are you worried about?

Actually scratch that concern. It's just that I'm not too versed in the WP hooks engine, and thought we might not want to have multiple callbacks for the same action, but thinking again, that's actually a feature and a legit use-case.

@fullofcaffeine
Copy link
Member Author

Great question. We will have to examine what exactly componenDidCatch exposes in error and info params.

Any group of people in the community that could help us audit this?

@fullofcaffeine fullofcaffeine requested a review from gziolo July 4, 2022 23:16
@gziolo
Copy link
Member

gziolo commented Jul 7, 2022

For the first iteration, we can proceed with the unified way of calling the action that has usage documented in the reference guide. The closest page to what we need here would be Editor Filters:

https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/filters/editor-filters.md

The name is a bit confusing when I think about it, because we are dealing with the action here. However, it's a structural mistake of calling hooks - filters in the Gutenberg documentation 😞

As for the filter name, it looks like we aren't consistent with using the name of the package as the prefix so we can go with the general editor. one. How about the following:

doAction( 'editor.ErrorBoundary.errorLogged', error, errorInfo );

…dditional error reporting logic for Error Boundaries
Separate navigation editor screen development is on hold.
@fullofcaffeine fullofcaffeine force-pushed the add/error-reporting-action-hooks-to-error-boundaries branch from b69f546 to 32671b5 Compare July 8, 2022 22:38
@@ -0,0 +1,38 @@
/**
Copy link
Member Author

@fullofcaffeine fullofcaffeine Jul 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit-tests are identical but simple enough, but there's one for each error boundary, which is a symptom of the existing unDRYness for Error Boundaries. We can turn them into a single test once we work on #42024 (comment).

Copy link
Member Author

@fullofcaffeine fullofcaffeine Jul 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we plan to work on #42024 (comment) soon, I'll abstain from trying to DRY the unit-tests (by extracting the common logic into a shared function or something along those lines, for example).

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start. Thank you @fullofcaffeine for bringing this task to the finish line.

The new documentation page is disconnected from the Block Editor Handbook. I will take care of changes to the Reference Guides separately as it requires some discussion how to rephrase all sections for filters to cover also actions similar to what you can see in WordPress core.

@gziolo gziolo merged commit d68dedb into trunk Jul 12, 2022
@gziolo gziolo deleted the add/error-reporting-action-hooks-to-error-boundaries branch July 12, 2022 07:33
@github-actions github-actions bot added this to the Gutenberg 13.7 milestone Jul 12, 2022
@gziolo gziolo added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Jul 12, 2022
@gziolo
Copy link
Member

gziolo commented Jul 12, 2022

I opened a follow-up that tries to re-structure documentation to better surface the new error logging capability for extenders.

I also marked this PR with the Needs Dev Note label as we definitely want to bring more attention once it lands in WordPress core. It's going to be a game changer for people willing to debug why the editor crashes on production.

@bph bph added the [Type] Developer Documentation Documentation for developers label Jul 12, 2022
@bph
Copy link
Contributor

bph commented Jul 12, 2022

I added Developer Documentation as reminder to double-check on this in time of 6.1

fullofcaffeine added a commit to Automattic/wp-calypso that referenced this pull request Jul 12, 2022
… in Gutenberg with Sentry

Register a callback to `editor.ErrorBoundary.errorLogged` action that will forward the error to Sentry everytime the action is called.

The action has been added to all active React Error Boundaries in Gutenberg in the following changeset: WordPress/gutenberg#42024 .
@bph bph removed [Type] Developer Documentation Documentation for developers labels Jul 12, 2022
fullofcaffeine added a commit to Automattic/wp-calypso that referenced this pull request Aug 5, 2022
… in Gutenberg with Sentry

Register a callback to `editor.ErrorBoundary.errorLogged` action that will forward the error to Sentry everytime the action is called.

The action has been added to all active React Error Boundaries in Gutenberg in the following changeset: WordPress/gutenberg#42024 .
fullofcaffeine added a commit to Automattic/wp-calypso that referenced this pull request Aug 5, 2022
… in Gutenberg with Sentry (#65503)

Register a callback to `editor.ErrorBoundary.errorLogged` action that will forward the error to Sentry everytime the action is called.

The action has been added to all active React Error Boundaries in Gutenberg in the following changeset: WordPress/gutenberg#42024 .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Developer Experience Ideas about improving block and theme developer experience [Feature] Extensibility The ability to extend blocks or the editing experience Needs Dev Note Requires a developer note for a major WordPress release cycle [Type] New API New API to be used by plugin developers or package users.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API proposal: allow setting an Error Reporting callback function for Error Boundaries using an action
4 participants