onunhandledrejection.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { defineIntegration, convertIntegrationFnToClass, getClient, captureException } from '@sentry/core';
  2. import { consoleSandbox } from '@sentry/utils';
  3. import { logAndExitProcess } from './utils/errorhandling.js';
  4. const INTEGRATION_NAME = 'OnUnhandledRejection';
  5. const _onUnhandledRejectionIntegration = ((options = {}) => {
  6. const mode = options.mode || 'warn';
  7. return {
  8. name: INTEGRATION_NAME,
  9. // TODO v8: Remove this
  10. setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
  11. setup(client) {
  12. global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, { mode }));
  13. },
  14. };
  15. }) ;
  16. const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);
  17. /**
  18. * Global Promise Rejection handler.
  19. * @deprecated Use `onUnhandledRejectionIntegration()` instead.
  20. */
  21. // eslint-disable-next-line deprecation/deprecation
  22. const OnUnhandledRejection = convertIntegrationFnToClass(
  23. INTEGRATION_NAME,
  24. onUnhandledRejectionIntegration,
  25. )
  26. ;
  27. // eslint-disable-next-line deprecation/deprecation
  28. /**
  29. * Send an exception with reason
  30. * @param reason string
  31. * @param promise promise
  32. *
  33. * Exported only for tests.
  34. */
  35. function makeUnhandledPromiseHandler(
  36. client,
  37. options,
  38. ) {
  39. return function sendUnhandledPromise(reason, promise) {
  40. if (getClient() !== client) {
  41. return;
  42. }
  43. captureException(reason, {
  44. originalException: promise,
  45. captureContext: {
  46. extra: { unhandledPromiseRejection: true },
  47. },
  48. mechanism: {
  49. handled: false,
  50. type: 'onunhandledrejection',
  51. },
  52. });
  53. handleRejection(reason, options);
  54. };
  55. }
  56. /**
  57. * Handler for `mode` option
  58. */
  59. function handleRejection(
  60. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  61. reason,
  62. options,
  63. ) {
  64. // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240
  65. const rejectionWarning =
  66. 'This error originated either by ' +
  67. 'throwing inside of an async function without a catch block, ' +
  68. 'or by rejecting a promise which was not handled with .catch().' +
  69. ' The promise rejected with the reason:';
  70. /* eslint-disable no-console */
  71. if (options.mode === 'warn') {
  72. consoleSandbox(() => {
  73. console.warn(rejectionWarning);
  74. // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
  75. console.error(reason && reason.stack ? reason.stack : reason);
  76. });
  77. } else if (options.mode === 'strict') {
  78. consoleSandbox(() => {
  79. console.warn(rejectionWarning);
  80. });
  81. logAndExitProcess(reason);
  82. }
  83. /* eslint-enable no-console */
  84. }
  85. export { OnUnhandledRejection, makeUnhandledPromiseHandler, onUnhandledRejectionIntegration };
  86. //# sourceMappingURL=onunhandledrejection.js.map