{"version":3,"sources":["../../../src/server/app-render/create-error-handler.tsx"],"sourcesContent":["import type { ErrorInfo } from 'react'\nimport stringHash from 'next/dist/compiled/string-hash'\n\nimport { formatServerError } from '../../lib/format-server-error'\nimport { SpanStatusCode, getTracer } from '../lib/trace/tracer'\n\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'\nimport { isInstantValidationError } from './instant-validation/instant-validation-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; environmentName?: 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  if (isInstantValidationError(error)) return error.digest\n\n  return undefined\n}\n\nexport function createReactServerErrorHandler(\n  shouldFormatError: boolean,\n  isBuildTimePrerendering: boolean,\n  reactServerErrors: Map<string, DigestedError>,\n  onReactServerRenderError: (err: DigestedError, silenceLog: boolean) => void,\n  spanToRecordOn?: any\n): RSCErrorHandler {\n  return (thrownValue: unknown) => {\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    let err = getProperError(thrownValue) as DigestedError\n    let silenceLog = false\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      const originalError = reactServerErrors.get(err.digest)\n\n      if (originalError) {\n        // This error crossed a react-server boundary (e.g. from a `'use cache'`\n        // render). Reaching the handler means it surfaced (it wasn't caught in\n        // userland), so stamp the digest onto the original to mark it surfaced.\n        // If the original was recorded as `invalidDynamicUsageError` without a\n        // digest (a cache that aborted across the boundary), this is what lets\n        // the dev overlay dedup: the separate forwarding checks for that digest\n        // and skips it.\n        originalError.digest ??= err.digest\n\n        if (process.env.NODE_ENV === 'production') {\n          // In production we use the recovered original (de-obfuscated!) error\n          // for reporting, and don't log it again as it was already logged in\n          // the original environment.\n          err = originalError\n          silenceLog = true\n        }\n      }\n    } else {\n      // TODO-APP: look at using webcrypto instead of string-hash. Requires a promise to be awaited.\n      err.digest =\n        typeof thrownValue === 'string'\n          ? stringHash(thrownValue).toString()\n          : createDigestWithErrorCode(\n              err,\n              stringHash(err.message + (err.stack || '')).toString()\n            )\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        isBuildTimePrerendering &&\n        err?.message?.includes(\n          'The specific message is omitted in production builds to avoid leaking sensitive details.'\n        )\n      )\n    ) {\n      // Record exception on the provided span if available, otherwise try active span.\n      const span = spanToRecordOn ?? 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, silenceLog)\n    }\n\n    return err.digest\n  }\n}\n\nexport function createHTMLErrorHandler(\n  shouldFormatError: boolean,\n  isBuildTimePrerendering: boolean,\n  reactServerErrors: Map<string, DigestedError>,\n  allCapturedErrors: Array<unknown>,\n  onHTMLRenderSSRError: (err: DigestedError, errorInfo?: ErrorInfo) => void,\n  spanToRecordOn?: any\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\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 = createDigestWithErrorCode(\n        err,\n        stringHash(\n          err.message + (errorInfo?.componentStack || err.stack || '')\n        ).toString()\n      )\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        isBuildTimePrerendering &&\n        err?.message?.includes(\n          'The specific message is omitted in production builds to avoid leaking sensitive details.'\n        )\n      )\n    ) {\n      // HTML errors contain RSC errors as well, filter them out before reporting\n      if (isSSRError) {\n        // Record exception on the provided span if available, otherwise try active span.\n        const span = spanToRecordOn ?? 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        onHTMLRenderSSRError(err, errorInfo)\n      }\n    }\n\n    return err.digest\n  }\n}\n\nexport function isUserLandError(err: any): boolean {\n  return (\n    !isAbortError(err) && !isBailoutToCSRError(err) && !isNextRouterError(err)\n  )\n}\n"],"names":["createHTMLErrorHandler","createReactServerErrorHandler","getDigestForWellKnownError","isUserLandError","error","isBailoutToCSRError","digest","isNextRouterError","isDynamicServerError","isPrerenderInterruptedError","isInstantValidationError","undefined","shouldFormatError","isBuildTimePrerendering","reactServerErrors","onReactServerRenderError","spanToRecordOn","thrownValue","err","isAbortError","isReactLargeShellError","console","getProperError","silenceLog","originalError","get","process","env","NODE_ENV","stringHash","toString","createDigestWithErrorCode","message","stack","has","set","formatServerError","includes","span","getTracer","getActiveScopeSpan","recordException","setAttribute","name","setStatus","code","SpanStatusCode","ERROR","allCapturedErrors","onHTMLRenderSSRError","errorInfo","isSSRError","push","componentStack"],"mappings":"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","ignoreList":[0]}