{"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 (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    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      if (\n        process.env.NODE_ENV === 'production' &&\n        reactServerErrors.has(err.digest)\n      ) {\n        // This error is likely an obfuscated error from another react-server\n        // environment (e.g. 'use cache'). We recover the original error here\n        // for reporting purposes.\n        err = reactServerErrors.get(err.digest)!\n        // We don't log it again though, as it was already logged in the\n        // original environment.\n        silenceLog = true\n      } else {\n        // Either we're in development (where we want to keep the transported\n        // error with environmentName), or the error is not in reactServerErrors\n        // but has a digest from other means. Keep the error as-is.\n      }\n    } else {\n      err.digest = createDigestWithErrorCode(\n        err,\n        // TODO-APP: look at using webcrypto instead. Requires a promise to be awaited.\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":["stringHash","formatServerError","SpanStatusCode","getTracer","isAbortError","isBailoutToCSRError","isDynamicServerError","isNextRouterError","isPrerenderInterruptedError","getProperError","createDigestWithErrorCode","isReactLargeShellError","isInstantValidationError","getDigestForWellKnownError","error","digest","undefined","createReactServerErrorHandler","shouldFormatError","isBuildTimePrerendering","reactServerErrors","onReactServerRenderError","spanToRecordOn","thrownValue","err","toString","console","silenceLog","process","env","NODE_ENV","has","get","message","stack","set","includes","span","getActiveScopeSpan","recordException","setAttribute","name","setStatus","code","ERROR","createHTMLErrorHandler","allCapturedErrors","onHTMLRenderSSRError","errorInfo","isSSRError","push","componentStack","isUserLandError"],"mappings":"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","ignoreList":[0]}