{"version":3,"sources":["../../../src/server/app-render/create-error-handler.tsx"],"sourcesContent":["import type { ErrorInfo } from 'react'\n\nimport stringHash from 'next/dist/compiled/string-hash'\nimport { formatServerError } from '../../lib/format-server-error'\nimport { SpanStatusCode, getTracer } from '../lib/trace/tracer'\nimport { isAbortError } from '../pipe-readable'\nimport { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr'\nimport { isDynamicServerError } from '../../client/components/hooks-server-context'\nimport { isNextRouterError } from '../../client/components/is-next-router-error'\nimport { isPrerenderInterruptedError } from './dynamic-rendering'\nimport { getProperError } from '../../lib/is-error'\nimport { createDigestWithErrorCode } from '../../lib/error-telemetry-utils'\nimport { isReactLargeShellError } from './react-large-shell-error'\n\ndeclare global {\n var __next_log_error__: undefined | ((err: unknown) => void)\n}\n\ntype RSCErrorHandler = (err: unknown) => string | undefined\ntype SSRErrorHandler = (\n err: unknown,\n errorInfo?: ErrorInfo\n) => string | undefined\n\nexport type DigestedError = Error & { digest: string }\n\n/**\n * Returns a digest for well-known Next.js errors, otherwise `undefined`. If a\n * digest is returned this also means that the error does not need to be\n * reported.\n */\nexport function getDigestForWellKnownError(error: unknown): string | undefined {\n // If we're bailing out to CSR, we don't need to log the error.\n if (isBailoutToCSRError(error)) return error.digest\n\n // If this is a navigation error, we don't need to log the error.\n if (isNextRouterError(error)) return error.digest\n\n // If this error occurs, we know that we should be stopping the static\n // render. This is only thrown in static generation when PPR is not enabled,\n // which causes the whole page to be marked as dynamic. We don't need to\n // tell the user about this error, as it's not actionable.\n if (isDynamicServerError(error)) return error.digest\n\n // If this is a prerender interrupted error, we don't need to log the error.\n if (isPrerenderInterruptedError(error)) return error.digest\n\n return undefined\n}\n\nexport function createFlightReactServerErrorHandler(\n shouldFormatError: boolean,\n onReactServerRenderError: (err: DigestedError) => void\n): RSCErrorHandler {\n return (thrownValue: unknown) => {\n if (typeof thrownValue === 'string') {\n // TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.\n return stringHash(thrownValue).toString()\n }\n\n // If the response was closed, we don't need to log the error.\n if (isAbortError(thrownValue)) return\n\n const digest = getDigestForWellKnownError(thrownValue)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(thrownValue)) {\n // TODO: Aggregate\n console.error(thrownValue)\n return undefined\n }\n\n const err = getProperError(thrownValue) as DigestedError\n\n // If the error already has a digest, respect the original digest,\n // so it won't get re-generated into another new error.\n if (!err.digest) {\n // TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.\n err.digest = stringHash(err.message + err.stack || '').toString()\n }\n\n // Format server errors in development to add more helpful error messages\n if (shouldFormatError) {\n formatServerError(err)\n }\n\n // Record exception in an active span, if available.\n const span = getTracer().getActiveScopeSpan()\n if (span) {\n span.recordException(err)\n span.setAttribute('error.type', err.name)\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n })\n }\n\n onReactServerRenderError(err)\n\n return createDigestWithErrorCode(thrownValue, err.digest)\n }\n}\n\nexport function createHTMLReactServerErrorHandler(\n shouldFormatError: boolean,\n isNextExport: boolean,\n reactServerErrors: Map,\n silenceLogger: boolean,\n onReactServerRenderError: undefined | ((err: DigestedError) => void)\n): RSCErrorHandler {\n return (thrownValue: unknown) => {\n if (typeof thrownValue === 'string') {\n // TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.\n return stringHash(thrownValue).toString()\n }\n\n // If the response was closed, we don't need to log the error.\n if (isAbortError(thrownValue)) return\n\n const digest = getDigestForWellKnownError(thrownValue)\n\n if (digest) {\n return digest\n }\n\n if (isReactLargeShellError(thrownValue)) {\n // TODO: Aggregate\n console.error(thrownValue)\n return undefined\n }\n\n const err = getProperError(thrownValue) as DigestedError\n\n // If the error already has a digest, respect the original digest,\n // so it won't get re-generated into another new error.\n if (!err.digest) {\n // TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.\n err.digest = stringHash(err.message + (err.stack || '')).toString()\n }\n\n // @TODO by putting this here and not at the top it is possible that\n // we don't error the build in places we actually expect to\n if (!reactServerErrors.has(err.digest)) {\n reactServerErrors.set(err.digest, err)\n }\n\n // Format server errors in development to add more helpful error messages\n if (shouldFormatError) {\n formatServerError(err)\n }\n\n // Don't log the suppressed error during export\n if (\n !(\n isNextExport &&\n err?.message?.includes(\n 'The specific message is omitted in production builds to avoid leaking sensitive details.'\n )\n )\n ) {\n // Record exception in an active span, if available.\n const span = getTracer().getActiveScopeSpan()\n if (span) {\n span.recordException(err)\n span.setAttribute('error.type', err.name)\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n })\n }\n\n if (!silenceLogger) {\n onReactServerRenderError?.(err)\n }\n }\n\n return createDigestWithErrorCode(thrownValue, err.digest)\n }\n}\n\nexport function createHTMLErrorHandler(\n shouldFormatError: boolean,\n isNextExport: boolean,\n reactServerErrors: Map,\n allCapturedErrors: Array,\n silenceLogger: boolean,\n onHTMLRenderSSRError: (err: DigestedError, errorInfo?: ErrorInfo) => void\n): SSRErrorHandler {\n return (thrownValue: unknown, errorInfo?: ErrorInfo) => {\n if (isReactLargeShellError(thrownValue)) {\n // TODO: Aggregate\n console.error(thrownValue)\n return undefined\n }\n\n let isSSRError = true\n\n allCapturedErrors.push(thrownValue)\n\n // If the response was closed, we don't need to log the error.\n if (isAbortError(thrownValue)) return\n\n const digest = getDigestForWellKnownError(thrownValue)\n\n if (digest) {\n return digest\n }\n\n const err = getProperError(thrownValue) as DigestedError\n // If the error already has a digest, respect the original digest,\n // so it won't get re-generated into another new error.\n if (err.digest) {\n if (reactServerErrors.has(err.digest)) {\n // This error is likely an obfuscated error from react-server.\n // We recover the original error here.\n thrownValue = reactServerErrors.get(err.digest)\n isSSRError = false\n } else {\n // The error is not from react-server but has a digest\n // from other means so we don't need to produce a new one\n }\n } else {\n err.digest = stringHash(\n err.message + (errorInfo?.componentStack || err.stack || '')\n ).toString()\n }\n\n // Format server errors in development to add more helpful error messages\n if (shouldFormatError) {\n formatServerError(err)\n }\n\n // Don't log the suppressed error during export\n if (\n !(\n isNextExport &&\n err?.message?.includes(\n 'The specific message is omitted in production builds to avoid leaking sensitive details.'\n )\n )\n ) {\n // Record exception in an active span, if available.\n const span = getTracer().getActiveScopeSpan()\n if (span) {\n span.recordException(err)\n span.setAttribute('error.type', err.name)\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n })\n }\n\n if (\n !silenceLogger &&\n // HTML errors contain RSC errors as well, filter them out before reporting\n isSSRError\n ) {\n onHTMLRenderSSRError(err, errorInfo)\n }\n }\n\n return createDigestWithErrorCode(thrownValue, err.digest)\n }\n}\n\nexport function isUserLandError(err: any): boolean {\n return (\n !isAbortError(err) && !isBailoutToCSRError(err) && !isNextRouterError(err)\n )\n}\n"],"names":["createFlightReactServerErrorHandler","createHTMLErrorHandler","createHTMLReactServerErrorHandler","getDigestForWellKnownError","isUserLandError","error","isBailoutToCSRError","digest","isNextRouterError","isDynamicServerError","isPrerenderInterruptedError","undefined","shouldFormatError","onReactServerRenderError","thrownValue","stringHash","toString","isAbortError","isReactLargeShellError","console","err","getProperError","message","stack","formatServerError","span","getTracer","getActiveScopeSpan","recordException","setAttribute","name","setStatus","code","SpanStatusCode","ERROR","createDigestWithErrorCode","isNextExport","reactServerErrors","silenceLogger","has","set","includes","allCapturedErrors","onHTMLRenderSSRError","errorInfo","isSSRError","push","get","componentStack"],"mappings":"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","ignoreList":[0]}