Skip to content

Commit

Permalink
feat: add component stack to recoverable error
Browse files Browse the repository at this point in the history
Attaches any component stack from error info to the error object on a recoverable error. This will help understanding hydration mismatch errors in production logs.
  • Loading branch information
AndersDJohnson authored Jun 8, 2023
1 parent 0d46361 commit 1470e29
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions packages/next/src/client/on-recoverable-error.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
import { NEXT_DYNAMIC_NO_SSR_CODE } from '../shared/lib/lazy-dynamic/no-ssr-error'

export default function onRecoverableError(err: any) {
/**
* @see [ReactInternalTypes]{@link https://github.com/facebook/react/blob/910045696bb5f693acb77890e6750c5e4659b420/packages/react-reconciler/src/ReactInternalTypes.js#L278-L281}
*/
interface ErrorInfo {
componentStack?: string
}

export default function onRecoverableError(err: any, errorInfo: ErrorInfo) {
// Attach any component stack to the error, so it's accessible when passed thru `reportError` below,
// such as from custom `window.onerror` or `window` `error` event listeners in an app.
// Similar is done in `@next/react-dev-overlay`, but this supports production use cases as well.
// This is technically a mutation of an argument, which is generally inadvisable, but probably not problematic in this case.
// The alternative of constucting a new error could be more complicated.
if (errorInfo.componentStack) {
err._componentStack = errorInfo.componentStack
}

// Using default react onRecoverableError
// x-ref: https://github.com/facebook/react/blob/d4bc16a7d69eb2ea38a88c8ac0b461d5f72cdcab/packages/react-dom/src/client/ReactDOMRoot.js#L83
const defaultOnRecoverableError =
typeof reportError === 'function'
? // In modern browsers, reportError will dispatch an error event,
// emulating an uncaught JavaScript error.
reportError
: (error: any) => {
window.console.error(error)
: (error: any, errorInfo: ErrorInfo) => {
window.console.error(error, errorInfo)
}

// Skip certain custom errors which are not expected to be reported on client
if (err.digest === NEXT_DYNAMIC_NO_SSR_CODE) return
defaultOnRecoverableError(err)

defaultOnRecoverableError(err, errorInfo)
}

0 comments on commit 1470e29

Please sign in to comment.