wrapPageComponentWithSentry.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { _optionalChain } from '@sentry/utils';
  2. import { addTracingExtensions, runWithAsyncContext, getCurrentScope, captureException } from '@sentry/core';
  3. import { extractTraceparentData } from '@sentry/utils';
  4. function isReactClassComponent(target) {
  5. // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
  6. return typeof target === 'function' && _optionalChain([target, 'optionalAccess', _ => _.prototype, 'optionalAccess', _2 => _2.isReactComponent]);
  7. }
  8. /**
  9. * Wraps a page component with Sentry error instrumentation.
  10. */
  11. function wrapPageComponentWithSentry(pageComponent) {
  12. addTracingExtensions();
  13. if (isReactClassComponent(pageComponent)) {
  14. return class SentryWrappedPageComponent extends pageComponent {
  15. render(...args) {
  16. return runWithAsyncContext(() => {
  17. const scope = getCurrentScope();
  18. // We extract the sentry trace data that is put in the component props by datafetcher wrappers
  19. const sentryTraceData =
  20. typeof this.props === 'object' &&
  21. this.props !== null &&
  22. '_sentryTraceData' in this.props &&
  23. typeof this.props._sentryTraceData === 'string'
  24. ? this.props._sentryTraceData
  25. : undefined;
  26. if (sentryTraceData) {
  27. const traceparentData = extractTraceparentData(sentryTraceData);
  28. scope.setContext('trace', {
  29. span_id: _optionalChain([traceparentData, 'optionalAccess', _3 => _3.parentSpanId]),
  30. trace_id: _optionalChain([traceparentData, 'optionalAccess', _4 => _4.traceId]),
  31. });
  32. }
  33. try {
  34. return super.render(...args);
  35. } catch (e) {
  36. captureException(e, {
  37. mechanism: {
  38. handled: false,
  39. },
  40. });
  41. throw e;
  42. }
  43. });
  44. }
  45. };
  46. } else if (typeof pageComponent === 'function') {
  47. return new Proxy(pageComponent, {
  48. apply(target, thisArg, argArray) {
  49. return runWithAsyncContext(() => {
  50. const scope = getCurrentScope();
  51. // We extract the sentry trace data that is put in the component props by datafetcher wrappers
  52. const sentryTraceData = _optionalChain([argArray, 'optionalAccess', _5 => _5[0], 'optionalAccess', _6 => _6._sentryTraceData]);
  53. if (sentryTraceData) {
  54. const traceparentData = extractTraceparentData(sentryTraceData);
  55. scope.setContext('trace', {
  56. span_id: _optionalChain([traceparentData, 'optionalAccess', _7 => _7.parentSpanId]),
  57. trace_id: _optionalChain([traceparentData, 'optionalAccess', _8 => _8.traceId]),
  58. });
  59. }
  60. try {
  61. return target.apply(thisArg, argArray);
  62. } catch (e) {
  63. captureException(e, {
  64. mechanism: {
  65. handled: false,
  66. },
  67. });
  68. throw e;
  69. }
  70. });
  71. },
  72. });
  73. } else {
  74. return pageComponent;
  75. }
  76. }
  77. export { wrapPageComponentWithSentry };
  78. //# sourceMappingURL=wrapPageComponentWithSentry.js.map