{"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":["createHTMLErrorHandler","createReactServerErrorHandler","getDigestForWellKnownError","isUserLandError","error","isBailoutToCSRError","digest","isNextRouterError","isDynamicServerError","isPrerenderInterruptedError","isInstantValidationError","undefined","shouldFormatError","isBuildTimePrerendering","reactServerErrors","onReactServerRenderError","spanToRecordOn","thrownValue","err","stringHash","toString","isAbortError","isReactLargeShellError","console","getProperError","silenceLog","process","env","NODE_ENV","has","get","createDigestWithErrorCode","message","stack","set","formatServerError","includes","span","getTracer","getActiveScopeSpan","recordException","setAttribute","name","setStatus","code","SpanStatusCode","ERROR","allCapturedErrors","onHTMLRenderSSRError","errorInfo","isSSRError","push","componentStack"],"mappings":";;;;;;;;;;;;;;;;;IAsJgBA,sBAAsB;eAAtBA;;IAhGAC,6BAA6B;eAA7BA;;IArBAC,0BAA0B;eAA1BA;;IA2MAC,eAAe;eAAfA;;;mEA3OO;mCAEW;wBACQ;8BAEb;8BACO;oCACC;mCACH;kCACU;yBACb;qCACW;sCACH;wCACE;;;;;;AAmBlC,SAASD,2BAA2BE,KAAc;IACvD,+DAA+D;IAC/D,IAAIC,IAAAA,iCAAmB,EAACD,QAAQ,OAAOA,MAAME,MAAM;IAEnD,iEAAiE;IACjE,IAAIC,IAAAA,oCAAiB,EAACH,QAAQ,OAAOA,MAAME,MAAM;IAEjD,sEAAsE;IACtE,4EAA4E;IAC5E,wEAAwE;IACxE,0DAA0D;IAC1D,IAAIE,IAAAA,wCAAoB,EAACJ,QAAQ,OAAOA,MAAME,MAAM;IAEpD,4EAA4E;IAC5E,IAAIG,IAAAA,6CAA2B,EAACL,QAAQ,OAAOA,MAAME,MAAM;IAE3D,IAAII,IAAAA,gDAAwB,EAACN,QAAQ,OAAOA,MAAME,MAAM;IAExD,OAAOK;AACT;AAEO,SAASV,8BACdW,iBAA0B,EAC1BC,uBAAgC,EAChCC,iBAA6C,EAC7CC,wBAA2E,EAC3EC,cAAoB;IAEpB,OAAO,CAACC;YAkEFC;QAjEJ,IAAI,OAAOD,gBAAgB,UAAU;YACnC,+EAA+E;YAC/E,OAAOE,IAAAA,mBAAU,EAACF,aAAaG,QAAQ;QACzC;QAEA,8DAA8D;QAC9D,IAAIC,IAAAA,0BAAY,EAACJ,cAAc;QAE/B,MAAMX,SAASJ,2BAA2Be;QAE1C,IAAIX,QAAQ;YACV,OAAOA;QACT;QAEA,IAAIgB,IAAAA,4CAAsB,EAACL,cAAc;YACvC,kBAAkB;YAClBM,QAAQnB,KAAK,CAACa;YACd,OAAON;QACT;QAEA,IAAIO,MAAMM,IAAAA,uBAAc,EAACP;QACzB,IAAIQ,aAAa;QAEjB,kEAAkE;QAClE,uDAAuD;QACvD,IAAIP,IAAIZ,MAAM,EAAE;YACd,IACEoB,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBACzBd,kBAAkBe,GAAG,CAACX,IAAIZ,MAAM,GAChC;gBACA,qEAAqE;gBACrE,qEAAqE;gBACrE,0BAA0B;gBAC1BY,MAAMJ,kBAAkBgB,GAAG,CAACZ,IAAIZ,MAAM;gBACtC,gEAAgE;gBAChE,wBAAwB;gBACxBmB,aAAa;YACf,OAAO;YACL,qEAAqE;YACrE,wEAAwE;YACxE,2DAA2D;YAC7D;QACF,OAAO;YACLP,IAAIZ,MAAM,GAAGyB,IAAAA,8CAAyB,EACpCb,KACA,+EAA+E;YAC/EC,IAAAA,mBAAU,EAACD,IAAIc,OAAO,GAAId,CAAAA,IAAIe,KAAK,IAAI,EAAC,GAAIb,QAAQ;QAExD;QAEA,oEAAoE;QACpE,2DAA2D;QAC3D,IAAI,CAACN,kBAAkBe,GAAG,CAACX,IAAIZ,MAAM,GAAG;YACtCQ,kBAAkBoB,GAAG,CAAChB,IAAIZ,MAAM,EAAEY;QACpC;QAEA,yEAAyE;QACzE,IAAIN,mBAAmB;YACrBuB,IAAAA,oCAAiB,EAACjB;QACpB;QAEA,+CAA+C;QAC/C,IACE,CACEL,CAAAA,4BACAK,wBAAAA,eAAAA,IAAKc,OAAO,qBAAZd,aAAckB,QAAQ,CACpB,4FACF,GAEF;YACA,iFAAiF;YACjF,MAAMC,OAAOrB,kBAAkBsB,IAAAA,iBAAS,IAAGC,kBAAkB;YAC7D,IAAIF,MAAM;gBACRA,KAAKG,eAAe,CAACtB;gBACrBmB,KAAKI,YAAY,CAAC,cAAcvB,IAAIwB,IAAI;gBACxCL,KAAKM,SAAS,CAAC;oBACbC,MAAMC,sBAAc,CAACC,KAAK;oBAC1Bd,SAASd,IAAIc,OAAO;gBACtB;YACF;YAEAjB,yBAAyBG,KAAKO;QAChC;QAEA,OAAOP,IAAIZ,MAAM;IACnB;AACF;AAEO,SAASN,uBACdY,iBAA0B,EAC1BC,uBAAgC,EAChCC,iBAA6C,EAC7CiC,iBAAiC,EACjCC,oBAAyE,EACzEhC,cAAoB;IAEpB,OAAO,CAACC,aAAsBgC;YAoDxB/B;QAnDJ,IAAII,IAAAA,4CAAsB,EAACL,cAAc;YACvC,kBAAkB;YAClBM,QAAQnB,KAAK,CAACa;YACd,OAAON;QACT;QAEA,IAAIuC,aAAa;QAEjBH,kBAAkBI,IAAI,CAAClC;QAEvB,8DAA8D;QAC9D,IAAII,IAAAA,0BAAY,EAACJ,cAAc;QAE/B,MAAMX,SAASJ,2BAA2Be;QAE1C,IAAIX,QAAQ;YACV,OAAOA;QACT;QAEA,MAAMY,MAAMM,IAAAA,uBAAc,EAACP;QAE3B,kEAAkE;QAClE,uDAAuD;QACvD,IAAIC,IAAIZ,MAAM,EAAE;YACd,IAAIQ,kBAAkBe,GAAG,CAACX,IAAIZ,MAAM,GAAG;gBACrC,8DAA8D;gBAC9D,sCAAsC;gBACtCW,cAAcH,kBAAkBgB,GAAG,CAACZ,IAAIZ,MAAM;gBAC9C4C,aAAa;YACf,OAAO;YACL,sDAAsD;YACtD,yDAAyD;YAC3D;QACF,OAAO;YACLhC,IAAIZ,MAAM,GAAGyB,IAAAA,8CAAyB,EACpCb,KACAC,IAAAA,mBAAU,EACRD,IAAIc,OAAO,GAAIiB,CAAAA,CAAAA,6BAAAA,UAAWG,cAAc,KAAIlC,IAAIe,KAAK,IAAI,EAAC,GAC1Db,QAAQ;QAEd;QAEA,yEAAyE;QACzE,IAAIR,mBAAmB;YACrBuB,IAAAA,oCAAiB,EAACjB;QACpB;QAEA,+CAA+C;QAC/C,IACE,CACEL,CAAAA,4BACAK,wBAAAA,eAAAA,IAAKc,OAAO,qBAAZd,aAAckB,QAAQ,CACpB,4FACF,GAEF;YACA,2EAA2E;YAC3E,IAAIc,YAAY;gBACd,iFAAiF;gBACjF,MAAMb,OAAOrB,kBAAkBsB,IAAAA,iBAAS,IAAGC,kBAAkB;gBAC7D,IAAIF,MAAM;oBACRA,KAAKG,eAAe,CAACtB;oBACrBmB,KAAKI,YAAY,CAAC,cAAcvB,IAAIwB,IAAI;oBACxCL,KAAKM,SAAS,CAAC;wBACbC,MAAMC,sBAAc,CAACC,KAAK;wBAC1Bd,SAASd,IAAIc,OAAO;oBACtB;gBACF;gBAEAgB,qBAAqB9B,KAAK+B;YAC5B;QACF;QAEA,OAAO/B,IAAIZ,MAAM;IACnB;AACF;AAEO,SAASH,gBAAgBe,GAAQ;IACtC,OACE,CAACG,IAAAA,0BAAY,EAACH,QAAQ,CAACb,IAAAA,iCAAmB,EAACa,QAAQ,CAACX,IAAAA,oCAAiB,EAACW;AAE1E","ignoreList":[0]}