extraerrordata.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { defineIntegration, convertIntegrationFnToClass } from '@sentry/core';
  2. import { isError, normalize, isPlainObject, addNonEnumerableProperty, logger } from '@sentry/utils';
  3. import { DEBUG_BUILD } from './debug-build.js';
  4. const INTEGRATION_NAME = 'ExtraErrorData';
  5. const _extraErrorDataIntegration = ((options = {}) => {
  6. const depth = options.depth || 3;
  7. // TODO(v8): Flip the default for this option to true
  8. const captureErrorCause = options.captureErrorCause || false;
  9. return {
  10. name: INTEGRATION_NAME,
  11. // TODO v8: Remove this
  12. setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
  13. processEvent(event, hint) {
  14. return _enhanceEventWithErrorData(event, hint, depth, captureErrorCause);
  15. },
  16. };
  17. }) ;
  18. const extraErrorDataIntegration = defineIntegration(_extraErrorDataIntegration);
  19. /**
  20. * Extract additional data for from original exceptions.
  21. * @deprecated Use `extraErrorDataIntegration()` instead.
  22. */
  23. // eslint-disable-next-line deprecation/deprecation
  24. const ExtraErrorData = convertIntegrationFnToClass(
  25. INTEGRATION_NAME,
  26. extraErrorDataIntegration,
  27. )
  28. ;
  29. function _enhanceEventWithErrorData(
  30. event,
  31. hint = {},
  32. depth,
  33. captureErrorCause,
  34. ) {
  35. if (!hint.originalException || !isError(hint.originalException)) {
  36. return event;
  37. }
  38. const exceptionName = (hint.originalException ).name || hint.originalException.constructor.name;
  39. const errorData = _extractErrorData(hint.originalException , captureErrorCause);
  40. if (errorData) {
  41. const contexts = {
  42. ...event.contexts,
  43. };
  44. const normalizedErrorData = normalize(errorData, depth);
  45. if (isPlainObject(normalizedErrorData)) {
  46. // We mark the error data as "already normalized" here, because we don't want other normalization procedures to
  47. // potentially truncate the data we just already normalized, with a certain depth setting.
  48. addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true);
  49. contexts[exceptionName] = normalizedErrorData;
  50. }
  51. return {
  52. ...event,
  53. contexts,
  54. };
  55. }
  56. return event;
  57. }
  58. /**
  59. * Extract extra information from the Error object
  60. */
  61. function _extractErrorData(error, captureErrorCause) {
  62. // We are trying to enhance already existing event, so no harm done if it won't succeed
  63. try {
  64. const nativeKeys = [
  65. 'name',
  66. 'message',
  67. 'stack',
  68. 'line',
  69. 'column',
  70. 'fileName',
  71. 'lineNumber',
  72. 'columnNumber',
  73. 'toJSON',
  74. ];
  75. const extraErrorInfo = {};
  76. // We want only enumerable properties, thus `getOwnPropertyNames` is redundant here, as we filter keys anyway.
  77. for (const key of Object.keys(error)) {
  78. if (nativeKeys.indexOf(key) !== -1) {
  79. continue;
  80. }
  81. const value = error[key];
  82. extraErrorInfo[key] = isError(value) ? value.toString() : value;
  83. }
  84. // Error.cause is a standard property that is non enumerable, we therefore need to access it separately.
  85. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
  86. if (captureErrorCause && error.cause !== undefined) {
  87. extraErrorInfo.cause = isError(error.cause) ? error.cause.toString() : error.cause;
  88. }
  89. // Check if someone attached `toJSON` method to grab even more properties (eg. axios is doing that)
  90. if (typeof error.toJSON === 'function') {
  91. const serializedError = error.toJSON() ;
  92. for (const key of Object.keys(serializedError)) {
  93. const value = serializedError[key];
  94. extraErrorInfo[key] = isError(value) ? value.toString() : value;
  95. }
  96. }
  97. return extraErrorInfo;
  98. } catch (oO) {
  99. DEBUG_BUILD && logger.error('Unable to extract extra data from the Error object:', oO);
  100. }
  101. return null;
  102. }
  103. export { ExtraErrorData, extraErrorDataIntegration };
  104. //# sourceMappingURL=extraerrordata.js.map