{"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import type { Client, IntegrationFn, SeverityLevel, Span } from '@sentry/core';\nimport {\n  captureException,\n  consoleSandbox,\n  defineIntegration,\n  getClient,\n  isMatchingPattern,\n  withActiveSpan,\n} from '@sentry/core';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\n\ntype IgnoreMatcher = { name?: string | RegExp; message?: string | RegExp };\n\ninterface OnUnhandledRejectionOptions {\n  /**\n   * Option deciding what to do after capturing unhandledRejection,\n   * that mimicks behavior of node's --unhandled-rejection flag.\n   */\n  mode: UnhandledRejectionMode;\n  /** Rejection Errors to ignore (don't capture or warn). */\n  ignore?: IgnoreMatcher[];\n}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst DEFAULT_IGNORES: IgnoreMatcher[] = [\n  {\n    name: 'AI_NoOutputGeneratedError', // When stream aborts in Vercel AI SDK V5, Vercel flush() fails with an error\n  },\n  {\n    name: 'AbortError', // When stream aborts in Vercel AI SDK V6\n  },\n];\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n  const opts: OnUnhandledRejectionOptions = {\n    mode: options.mode ?? 'warn',\n    ignore: [...DEFAULT_IGNORES, ...(options.ignore ?? [])],\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    setup(client) {\n      global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, opts));\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/** Extract error info safely */\nfunction extractErrorInfo(reason: unknown): { name: string; message: string } {\n  // Check if reason is an object (including Error instances, not just plain objects)\n  if (typeof reason !== 'object' || reason === null) {\n    return { name: '', message: String(reason ?? '') };\n  }\n\n  const errorLike = reason as Record<string, unknown>;\n  const name = typeof errorLike.name === 'string' ? errorLike.name : '';\n  const message = typeof errorLike.message === 'string' ? errorLike.message : String(reason);\n\n  return { name, message };\n}\n\n/** Check if a matcher matches the reason */\nfunction isMatchingReason(matcher: IgnoreMatcher, errorInfo: ReturnType<typeof extractErrorInfo>): boolean {\n  // name/message matcher\n  const nameMatches = matcher.name === undefined || isMatchingPattern(errorInfo.name, matcher.name, true);\n\n  const messageMatches = matcher.message === undefined || isMatchingPattern(errorInfo.message, matcher.message);\n\n  return nameMatches && messageMatches;\n}\n\n/** Match helper */\nfunction matchesIgnore(list: IgnoreMatcher[], reason: unknown): boolean {\n  const errorInfo = extractErrorInfo(reason);\n  return list.some(matcher => isMatchingReason(matcher, errorInfo));\n}\n\n/** Core handler */\nexport function makeUnhandledPromiseHandler(\n  client: Client,\n  options: OnUnhandledRejectionOptions,\n): (reason: unknown, promise: unknown) => void {\n  return function sendUnhandledPromise(reason: unknown, _promise: unknown): void {\n    // Only handle for the active client\n    if (getClient() !== client) {\n      return;\n    }\n\n    // Skip if configured to ignore\n    if (matchesIgnore(options.ignore ?? [], reason)) {\n      return;\n    }\n\n    const level: SeverityLevel = options.mode === 'strict' ? 'fatal' : 'error';\n\n    // this can be set in places where we cannot reliably get access to the active span/error\n    // when the error bubbles up to this handler, we can use this to set the active span\n    const activeSpanForError =\n      reason && typeof reason === 'object' ? (reason as { _sentry_active_span?: Span })._sentry_active_span : undefined;\n\n    const activeSpanWrapper = activeSpanForError\n      ? (fn: () => void) => withActiveSpan(activeSpanForError, fn)\n      : (fn: () => void) => fn();\n\n    activeSpanWrapper(() => {\n      captureException(reason, {\n        originalException: reason,\n        captureContext: {\n          extra: { unhandledPromiseRejection: true },\n          level,\n        },\n        mechanism: {\n          handled: false,\n          type: 'auto.node.onunhandledrejection',\n        },\n      });\n    });\n\n    handleRejection(reason, options.mode);\n  };\n}\n\n/**\n * Handler for `mode` option\n */\nfunction handleRejection(reason: unknown, mode: UnhandledRejectionMode): void {\n  // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240\n  const rejectionWarning =\n    'This error originated either by ' +\n    'throwing inside of an async function without a catch block, ' +\n    'or by rejecting a promise which was not handled with .catch().' +\n    ' The promise rejected with the reason:';\n\n  /* eslint-disable no-console */\n  if (mode === 'warn') {\n    consoleSandbox(() => {\n      console.warn(rejectionWarning);\n      console.error(reason && typeof reason === 'object' && 'stack' in reason ? reason.stack : reason);\n    });\n  } else if (mode === 'strict') {\n    consoleSandbox(() => {\n      console.warn(rejectionWarning);\n    });\n    logAndExitProcess(reason);\n  }\n  /* eslint-enable no-console */\n}\n"],"names":[],"mappings":"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"}