@sentry/node 8.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/cjs/cron/common.js +56 -0
  2. package/cjs/cron/common.js.map +1 -0
  3. package/cjs/cron/cron.js +112 -0
  4. package/cjs/cron/cron.js.map +1 -0
  5. package/cjs/cron/index.js +15 -0
  6. package/cjs/cron/index.js.map +1 -0
  7. package/cjs/cron/node-cron.js +72 -0
  8. package/cjs/cron/node-cron.js.map +1 -0
  9. package/cjs/cron/node-schedule.js +69 -0
  10. package/cjs/cron/node-schedule.js.map +1 -0
  11. package/cjs/debug-build.js +11 -0
  12. package/cjs/debug-build.js.map +1 -0
  13. package/cjs/index.js +85 -4018
  14. package/cjs/index.js.map +1 -1
  15. package/cjs/integrations/anr/index.js +211 -0
  16. package/cjs/integrations/anr/index.js.map +1 -0
  17. package/cjs/integrations/console.js +40 -0
  18. package/cjs/integrations/console.js.map +1 -0
  19. package/cjs/integrations/context.js +435 -0
  20. package/cjs/integrations/context.js.map +1 -0
  21. package/cjs/integrations/contextlines.js +137 -0
  22. package/cjs/integrations/contextlines.js.map +1 -0
  23. package/cjs/integrations/http.js +161 -0
  24. package/cjs/integrations/http.js.map +1 -0
  25. package/cjs/integrations/local-variables/common.js +87 -0
  26. package/cjs/integrations/local-variables/common.js.map +1 -0
  27. package/cjs/integrations/local-variables/index.js +12 -0
  28. package/cjs/integrations/local-variables/index.js.map +1 -0
  29. package/cjs/integrations/local-variables/local-variables-async.js +149 -0
  30. package/cjs/integrations/local-variables/local-variables-async.js.map +1 -0
  31. package/cjs/integrations/local-variables/local-variables-sync.js +376 -0
  32. package/cjs/integrations/local-variables/local-variables-sync.js.map +1 -0
  33. package/cjs/integrations/modules.js +99 -0
  34. package/cjs/integrations/modules.js.map +1 -0
  35. package/cjs/integrations/node-fetch.js +81 -0
  36. package/cjs/integrations/node-fetch.js.map +1 -0
  37. package/cjs/integrations/onuncaughtexception.js +135 -0
  38. package/cjs/integrations/onuncaughtexception.js.map +1 -0
  39. package/cjs/integrations/onunhandledrejection.js +90 -0
  40. package/cjs/integrations/onunhandledrejection.js.map +1 -0
  41. package/cjs/integrations/spotlight.js +109 -0
  42. package/cjs/integrations/spotlight.js.map +1 -0
  43. package/cjs/integrations/tracing/connect.js +41 -0
  44. package/cjs/integrations/tracing/connect.js.map +1 -0
  45. package/cjs/integrations/tracing/express.js +127 -0
  46. package/cjs/integrations/tracing/express.js.map +1 -0
  47. package/cjs/integrations/tracing/fastify.js +84 -0
  48. package/cjs/integrations/tracing/fastify.js.map +1 -0
  49. package/cjs/integrations/tracing/graphql.js +32 -0
  50. package/cjs/integrations/tracing/graphql.js.map +1 -0
  51. package/cjs/integrations/tracing/hapi/index.js +106 -0
  52. package/cjs/integrations/tracing/hapi/index.js.map +1 -0
  53. package/cjs/integrations/tracing/index.js +43 -0
  54. package/cjs/integrations/tracing/index.js.map +1 -0
  55. package/cjs/integrations/tracing/koa.js +60 -0
  56. package/cjs/integrations/tracing/koa.js.map +1 -0
  57. package/cjs/integrations/tracing/mongo.js +31 -0
  58. package/cjs/integrations/tracing/mongo.js.map +1 -0
  59. package/cjs/integrations/tracing/mongoose.js +31 -0
  60. package/cjs/integrations/tracing/mongoose.js.map +1 -0
  61. package/cjs/integrations/tracing/mysql.js +24 -0
  62. package/cjs/integrations/tracing/mysql.js.map +1 -0
  63. package/cjs/integrations/tracing/mysql2.js +31 -0
  64. package/cjs/integrations/tracing/mysql2.js.map +1 -0
  65. package/cjs/integrations/tracing/nest.js +69 -0
  66. package/cjs/integrations/tracing/nest.js.map +1 -0
  67. package/cjs/integrations/tracing/postgres.js +32 -0
  68. package/cjs/integrations/tracing/postgres.js.map +1 -0
  69. package/cjs/integrations/tracing/prisma.js +48 -0
  70. package/cjs/integrations/tracing/prisma.js.map +1 -0
  71. package/cjs/integrations/tracing/redis.js +29 -0
  72. package/cjs/integrations/tracing/redis.js.map +1 -0
  73. package/cjs/nodeVersion.js +10 -0
  74. package/cjs/nodeVersion.js.map +1 -0
  75. package/cjs/otel/contextManager.js +16 -0
  76. package/cjs/otel/contextManager.js.map +1 -0
  77. package/cjs/proxy/base.js +127 -0
  78. package/cjs/proxy/base.js.map +1 -0
  79. package/cjs/proxy/index.js +178 -0
  80. package/cjs/proxy/index.js.map +1 -0
  81. package/cjs/proxy/parse-proxy-response.js +104 -0
  82. package/cjs/proxy/parse-proxy-response.js.map +1 -0
  83. package/cjs/sdk/api.js +45 -0
  84. package/cjs/sdk/api.js.map +1 -0
  85. package/cjs/sdk/client.js +63 -0
  86. package/cjs/sdk/client.js.map +1 -0
  87. package/cjs/sdk/init.js +318 -0
  88. package/cjs/sdk/init.js.map +1 -0
  89. package/cjs/sdk/initOtel.js +58 -0
  90. package/cjs/sdk/initOtel.js.map +1 -0
  91. package/cjs/sdk/scope.js +18 -0
  92. package/cjs/sdk/scope.js.map +1 -0
  93. package/cjs/transports/http.js +163 -0
  94. package/cjs/transports/http.js.map +1 -0
  95. package/cjs/utils/addOriginToSpan.js +11 -0
  96. package/cjs/utils/addOriginToSpan.js.map +1 -0
  97. package/cjs/utils/errorhandling.js +44 -0
  98. package/cjs/utils/errorhandling.js.map +1 -0
  99. package/cjs/utils/getRequestUrl.js +18 -0
  100. package/cjs/utils/getRequestUrl.js.map +1 -0
  101. package/cjs/utils/module.js +62 -0
  102. package/cjs/utils/module.js.map +1 -0
  103. package/esm/cron/common.js +54 -0
  104. package/esm/cron/common.js.map +1 -0
  105. package/esm/cron/cron.js +110 -0
  106. package/esm/cron/cron.js.map +1 -0
  107. package/esm/cron/index.js +13 -0
  108. package/esm/cron/index.js.map +1 -0
  109. package/esm/cron/node-cron.js +67 -0
  110. package/esm/cron/node-cron.js.map +1 -0
  111. package/esm/cron/node-schedule.js +64 -0
  112. package/esm/cron/node-schedule.js.map +1 -0
  113. package/esm/debug-build.js +9 -0
  114. package/esm/debug-build.js.map +1 -0
  115. package/esm/index.js +35 -3973
  116. package/esm/index.js.map +1 -1
  117. package/esm/integrations/anr/index.js +204 -0
  118. package/esm/integrations/anr/index.js.map +1 -0
  119. package/esm/integrations/anr/worker-script.js +2 -2
  120. package/esm/integrations/console.js +38 -0
  121. package/esm/integrations/console.js.map +1 -0
  122. package/esm/integrations/context.js +427 -0
  123. package/esm/integrations/context.js.map +1 -0
  124. package/esm/integrations/contextlines.js +131 -0
  125. package/esm/integrations/contextlines.js.map +1 -0
  126. package/esm/integrations/http.js +156 -0
  127. package/esm/integrations/http.js.map +1 -0
  128. package/esm/integrations/local-variables/common.js +81 -0
  129. package/esm/integrations/local-variables/common.js.map +1 -0
  130. package/esm/integrations/local-variables/index.js +10 -0
  131. package/esm/integrations/local-variables/index.js.map +1 -0
  132. package/esm/integrations/local-variables/local-variables-async.js +143 -0
  133. package/esm/integrations/local-variables/local-variables-async.js.map +1 -0
  134. package/esm/integrations/local-variables/local-variables-sync.js +370 -0
  135. package/esm/integrations/local-variables/local-variables-sync.js.map +1 -0
  136. package/esm/integrations/local-variables/worker-script.js +1 -1
  137. package/esm/integrations/modules.js +97 -0
  138. package/esm/integrations/modules.js.map +1 -0
  139. package/esm/integrations/node-fetch.js +79 -0
  140. package/esm/integrations/node-fetch.js.map +1 -0
  141. package/esm/integrations/onuncaughtexception.js +132 -0
  142. package/esm/integrations/onuncaughtexception.js.map +1 -0
  143. package/esm/integrations/onunhandledrejection.js +87 -0
  144. package/esm/integrations/onunhandledrejection.js.map +1 -0
  145. package/esm/integrations/spotlight.js +106 -0
  146. package/esm/integrations/spotlight.js.map +1 -0
  147. package/esm/integrations/tracing/connect.js +38 -0
  148. package/esm/integrations/tracing/connect.js.map +1 -0
  149. package/esm/integrations/tracing/express.js +120 -0
  150. package/esm/integrations/tracing/express.js.map +1 -0
  151. package/esm/integrations/tracing/fastify.js +78 -0
  152. package/esm/integrations/tracing/fastify.js.map +1 -0
  153. package/esm/integrations/tracing/graphql.js +30 -0
  154. package/esm/integrations/tracing/graphql.js.map +1 -0
  155. package/esm/integrations/tracing/hapi/index.js +99 -0
  156. package/esm/integrations/tracing/hapi/index.js.map +1 -0
  157. package/esm/integrations/tracing/index.js +41 -0
  158. package/esm/integrations/tracing/index.js.map +1 -0
  159. package/esm/integrations/tracing/koa.js +57 -0
  160. package/esm/integrations/tracing/koa.js.map +1 -0
  161. package/esm/integrations/tracing/mongo.js +29 -0
  162. package/esm/integrations/tracing/mongo.js.map +1 -0
  163. package/esm/integrations/tracing/mongoose.js +29 -0
  164. package/esm/integrations/tracing/mongoose.js.map +1 -0
  165. package/esm/integrations/tracing/mysql.js +22 -0
  166. package/esm/integrations/tracing/mysql.js.map +1 -0
  167. package/esm/integrations/tracing/mysql2.js +29 -0
  168. package/esm/integrations/tracing/mysql2.js.map +1 -0
  169. package/esm/integrations/tracing/nest.js +63 -0
  170. package/esm/integrations/tracing/nest.js.map +1 -0
  171. package/esm/integrations/tracing/postgres.js +30 -0
  172. package/esm/integrations/tracing/postgres.js.map +1 -0
  173. package/esm/integrations/tracing/prisma.js +43 -0
  174. package/esm/integrations/tracing/prisma.js.map +1 -0
  175. package/esm/integrations/tracing/redis.js +27 -0
  176. package/esm/integrations/tracing/redis.js.map +1 -0
  177. package/esm/nodeVersion.js +7 -0
  178. package/esm/nodeVersion.js.map +1 -0
  179. package/esm/otel/contextManager.js +14 -0
  180. package/esm/otel/contextManager.js.map +1 -0
  181. package/esm/proxy/base.js +122 -0
  182. package/esm/proxy/base.js.map +1 -0
  183. package/esm/proxy/index.js +172 -0
  184. package/esm/proxy/index.js.map +1 -0
  185. package/esm/proxy/parse-proxy-response.js +102 -0
  186. package/esm/proxy/parse-proxy-response.js.map +1 -0
  187. package/esm/sdk/api.js +42 -0
  188. package/esm/sdk/api.js.map +1 -0
  189. package/esm/sdk/client.js +58 -0
  190. package/esm/sdk/client.js.map +1 -0
  191. package/esm/sdk/init.js +312 -0
  192. package/esm/sdk/init.js.map +1 -0
  193. package/esm/sdk/initOtel.js +55 -0
  194. package/esm/sdk/initOtel.js.map +1 -0
  195. package/esm/sdk/scope.js +16 -0
  196. package/esm/sdk/scope.js.map +1 -0
  197. package/esm/transports/http.js +158 -0
  198. package/esm/transports/http.js.map +1 -0
  199. package/esm/utils/addOriginToSpan.js +9 -0
  200. package/esm/utils/addOriginToSpan.js.map +1 -0
  201. package/esm/utils/errorhandling.js +42 -0
  202. package/esm/utils/errorhandling.js.map +1 -0
  203. package/esm/utils/getRequestUrl.js +16 -0
  204. package/esm/utils/getRequestUrl.js.map +1 -0
  205. package/esm/utils/module.js +60 -0
  206. package/esm/utils/module.js.map +1 -0
  207. package/package.json +16 -16
  208. package/types/index.d.ts +2 -2
  209. package/types/index.d.ts.map +1 -1
  210. package/types/integrations/tracing/hapi/index.d.ts.map +1 -1
  211. package/types/integrations/tracing/koa.d.ts.map +1 -1
  212. package/types/sdk/init.d.ts +4 -0
  213. package/types/sdk/init.d.ts.map +1 -1
  214. package/types-ts3.8/index.d.ts +2 -2
  215. package/types-ts3.8/sdk/init.d.ts +4 -0
@@ -0,0 +1,79 @@
1
+ import { SpanKind } from '@opentelemetry/api';
2
+ import { defineIntegration, addBreadcrumb } from '@sentry/core';
3
+ import { addOpenTelemetryInstrumentation, getSpanKind, getRequestSpanData } from '@sentry/opentelemetry';
4
+ import { logger } from '@sentry/utils';
5
+ import { DEBUG_BUILD } from '../debug-build.js';
6
+ import { NODE_MAJOR } from '../nodeVersion.js';
7
+ import { addOriginToSpan } from '../utils/addOriginToSpan.js';
8
+
9
+ const _nativeNodeFetchIntegration = ((options = {}) => {
10
+ const _breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;
11
+ const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;
12
+
13
+ async function getInstrumentation() {
14
+ // Only add NodeFetch if Node >= 18, as previous versions do not support it
15
+ if (NODE_MAJOR < 18) {
16
+ DEBUG_BUILD && logger.log('NodeFetch is not supported on Node < 18, skipping instrumentation...');
17
+ return;
18
+ }
19
+
20
+ try {
21
+ const pkg = await import('opentelemetry-instrumentation-fetch-node');
22
+ return new pkg.FetchInstrumentation({
23
+ ignoreRequestHook: (request) => {
24
+ const url = request.origin;
25
+ return _ignoreOutgoingRequests && url && _ignoreOutgoingRequests(url);
26
+ },
27
+ onRequest: ({ span }) => {
28
+ _updateSpan(span);
29
+
30
+ if (_breadcrumbs) {
31
+ _addRequestBreadcrumb(span);
32
+ }
33
+ },
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ } );
36
+ } catch (error) {
37
+ // Could not load instrumentation
38
+ DEBUG_BUILD && logger.log('Could not load NodeFetch instrumentation.');
39
+ }
40
+ }
41
+
42
+ return {
43
+ name: 'NodeFetch',
44
+ setupOnce() {
45
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
46
+ getInstrumentation().then(instrumentation => {
47
+ if (instrumentation) {
48
+ addOpenTelemetryInstrumentation(instrumentation);
49
+ }
50
+ });
51
+ },
52
+ };
53
+ }) ;
54
+
55
+ const nativeNodeFetchIntegration = defineIntegration(_nativeNodeFetchIntegration);
56
+
57
+ /** Update the span with data we need. */
58
+ function _updateSpan(span) {
59
+ addOriginToSpan(span, 'auto.http.otel.node_fetch');
60
+ }
61
+
62
+ /** Add a breadcrumb for outgoing requests. */
63
+ function _addRequestBreadcrumb(span) {
64
+ if (getSpanKind(span) !== SpanKind.CLIENT) {
65
+ return;
66
+ }
67
+
68
+ const data = getRequestSpanData(span);
69
+ addBreadcrumb({
70
+ category: 'http',
71
+ data: {
72
+ ...data,
73
+ },
74
+ type: 'http',
75
+ });
76
+ }
77
+
78
+ export { nativeNodeFetchIntegration };
79
+ //# sourceMappingURL=node-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-fetch.js","sources":["../../../src/integrations/node-fetch.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport { SpanKind } from '@opentelemetry/api';\nimport { addBreadcrumb, defineIntegration } from '@sentry/core';\nimport { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';\nimport { getRequestSpanData, getSpanKind } from '@sentry/opentelemetry';\nimport type { IntegrationFn } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { NODE_MAJOR } from '../nodeVersion';\n\nimport type { FetchInstrumentation } from 'opentelemetry-instrumentation-fetch-node';\n\nimport { addOriginToSpan } from '../utils/addOriginToSpan';\n\ninterface NodeFetchOptions {\n /**\n * Whether breadcrumbs should be recorded for requests.\n * Defaults to true\n */\n breadcrumbs?: boolean;\n\n /**\n * Do not capture spans or breadcrumbs for outgoing fetch requests to URLs where the given callback returns `true`.\n * This controls both span & breadcrumb creation - spans will be non recording if tracing is disabled.\n */\n ignoreOutgoingRequests?: (url: string) => boolean;\n}\n\nconst _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => {\n const _breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;\n const _ignoreOutgoingRequests = options.ignoreOutgoingRequests;\n\n async function getInstrumentation(): Promise<FetchInstrumentation | void> {\n // Only add NodeFetch if Node >= 18, as previous versions do not support it\n if (NODE_MAJOR < 18) {\n DEBUG_BUILD && logger.log('NodeFetch is not supported on Node < 18, skipping instrumentation...');\n return;\n }\n\n try {\n const pkg = await import('opentelemetry-instrumentation-fetch-node');\n return new pkg.FetchInstrumentation({\n ignoreRequestHook: (request: { origin?: string }) => {\n const url = request.origin;\n return _ignoreOutgoingRequests && url && _ignoreOutgoingRequests(url);\n },\n onRequest: ({ span }: { span: Span }) => {\n _updateSpan(span);\n\n if (_breadcrumbs) {\n _addRequestBreadcrumb(span);\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n } catch (error) {\n // Could not load instrumentation\n DEBUG_BUILD && logger.log('Could not load NodeFetch instrumentation.');\n }\n }\n\n return {\n name: 'NodeFetch',\n setupOnce() {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n getInstrumentation().then(instrumentation => {\n if (instrumentation) {\n addOpenTelemetryInstrumentation(instrumentation);\n }\n });\n },\n };\n}) satisfies IntegrationFn;\n\nexport const nativeNodeFetchIntegration = defineIntegration(_nativeNodeFetchIntegration);\n\n/** Update the span with data we need. */\nfunction _updateSpan(span: Span): void {\n addOriginToSpan(span, 'auto.http.otel.node_fetch');\n}\n\n/** Add a breadcrumb for outgoing requests. */\nfunction _addRequestBreadcrumb(span: Span): void {\n if (getSpanKind(span) !== SpanKind.CLIENT) {\n return;\n }\n\n const data = getRequestSpanData(span);\n addBreadcrumb({\n category: 'http',\n data: {\n ...data,\n },\n type: 'http',\n });\n}\n"],"names":[],"mappings":";;;;;;;;AA4BA,MAAM,2BAAA,IAA+B,CAAC,OAAO,GAAqB,EAAE,KAAK;AACzE,EAAE,MAAM,YAAA,GAAe,OAAO,OAAO,CAAC,WAAA,KAAgB,WAAA,GAAc,IAAA,GAAO,OAAO,CAAC,WAAW,CAAA;AAC9F,EAAE,MAAM,uBAAA,GAA0B,OAAO,CAAC,sBAAsB,CAAA;AAChE;AACA,EAAE,eAAe,kBAAkB,GAAyC;AAC5E;AACA,IAAI,IAAI,UAAW,GAAE,EAAE,EAAE;AACzB,MAAM,eAAe,MAAM,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAA;AACvG,MAAM,OAAM;AACZ,KAAI;AACJ;AACA,IAAI,IAAI;AACR,MAAM,MAAM,GAAI,GAAE,MAAM,OAAO,0CAA0C,CAAC,CAAA;AAC1E,MAAM,OAAO,IAAI,GAAG,CAAC,oBAAoB,CAAC;AAC1C,QAAQ,iBAAiB,EAAE,CAAC,OAAO,KAA0B;AAC7D,UAAU,MAAM,GAAA,GAAM,OAAO,CAAC,MAAM,CAAA;AACpC,UAAU,OAAO,2BAA2B,GAAA,IAAO,uBAAuB,CAAC,GAAG,CAAC,CAAA;AAC/E,SAAS;AACT,QAAQ,SAAS,EAAE,CAAC,EAAE,IAAK,EAAC,KAAqB;AACjD,UAAU,WAAW,CAAC,IAAI,CAAC,CAAA;AAC3B;AACA,UAAU,IAAI,YAAY,EAAE;AAC5B,YAAY,qBAAqB,CAAC,IAAI,CAAC,CAAA;AACvC,WAAU;AACV,SAAS;AACT;AACA,SAAe,CAAA;AACf,KAAM,CAAA,OAAO,KAAK,EAAE;AACpB;AACA,MAAM,eAAe,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;AAC5E,KAAI;AACJ,GAAE;AACF;AACA,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,WAAW;AACrB,IAAI,SAAS,GAAG;AAChB;AACA,MAAM,kBAAkB,EAAE,CAAC,IAAI,CAAC,mBAAmB;AACnD,QAAQ,IAAI,eAAe,EAAE;AAC7B,UAAU,+BAA+B,CAAC,eAAe,CAAC,CAAA;AAC1D,SAAQ;AACR,OAAO,CAAC,CAAA;AACR,KAAK;AACL,GAAG,CAAA;AACH,CAAC,CAAE,EAAA;AACH;MACa,0BAA2B,GAAE,iBAAiB,CAAC,2BAA2B,EAAC;AACxF;AACA;AACA,SAAS,WAAW,CAAC,IAAI,EAAc;AACvC,EAAE,eAAe,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAA;AACpD,CAAA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,IAAI,EAAc;AACjD,EAAE,IAAI,WAAW,CAAC,IAAI,MAAM,QAAQ,CAAC,MAAM,EAAE;AAC7C,IAAI,OAAM;AACV,GAAE;AACF;AACA,EAAE,MAAM,IAAK,GAAE,kBAAkB,CAAC,IAAI,CAAC,CAAA;AACvC,EAAE,aAAa,CAAC;AAChB,IAAI,QAAQ,EAAE,MAAM;AACpB,IAAI,IAAI,EAAE;AACV,MAAM,GAAG,IAAI;AACb,KAAK;AACL,IAAI,IAAI,EAAE,MAAM;AAChB,GAAG,CAAC,CAAA;AACJ;;;;"}
@@ -0,0 +1,132 @@
1
+ import { defineIntegration, getClient, captureException } from '@sentry/core';
2
+ import { logger } from '@sentry/utils';
3
+ import { DEBUG_BUILD } from '../debug-build.js';
4
+ import { logAndExitProcess } from '../utils/errorhandling.js';
5
+
6
+ const INTEGRATION_NAME = 'OnUncaughtException';
7
+
8
+ /**
9
+ * Add a global exception handler.
10
+ */
11
+ const onUncaughtExceptionIntegration = defineIntegration((options = {}) => {
12
+ const optionsWithDefaults = {
13
+ exitEvenIfOtherHandlersAreRegistered: false,
14
+ ...options,
15
+ };
16
+
17
+ return {
18
+ name: INTEGRATION_NAME,
19
+ setup(client) {
20
+ global.process.on('uncaughtException', makeErrorHandler(client, optionsWithDefaults));
21
+ },
22
+ };
23
+ });
24
+
25
+ /** Exported only for tests */
26
+ function makeErrorHandler(client, options) {
27
+ const timeout = 2000;
28
+ let caughtFirstError = false;
29
+ let caughtSecondError = false;
30
+ let calledFatalError = false;
31
+ let firstError;
32
+
33
+ const clientOptions = client.getOptions();
34
+
35
+ return Object.assign(
36
+ (error) => {
37
+ let onFatalError = logAndExitProcess;
38
+
39
+ if (options.onFatalError) {
40
+ onFatalError = options.onFatalError;
41
+ } else if (clientOptions.onFatalError) {
42
+ onFatalError = clientOptions.onFatalError ;
43
+ }
44
+
45
+ // Attaching a listener to `uncaughtException` will prevent the node process from exiting. We generally do not
46
+ // want to alter this behaviour so we check for other listeners that users may have attached themselves and adjust
47
+ // exit behaviour of the SDK accordingly:
48
+ // - If other listeners are attached, do not exit.
49
+ // - If the only listener attached is ours, exit.
50
+ const userProvidedListenersCount = (global.process.listeners('uncaughtException') ).filter(
51
+ listener => {
52
+ // There are 3 listeners we ignore:
53
+ return (
54
+ // as soon as we're using domains this listener is attached by node itself
55
+ listener.name !== 'domainUncaughtExceptionClear' &&
56
+ // the handler we register for tracing
57
+ listener.tag !== 'sentry_tracingErrorCallback' &&
58
+ // the handler we register in this integration
59
+ (listener )._errorHandler !== true
60
+ );
61
+ },
62
+ ).length;
63
+
64
+ const processWouldExit = userProvidedListenersCount === 0;
65
+ const shouldApplyFatalHandlingLogic = options.exitEvenIfOtherHandlersAreRegistered || processWouldExit;
66
+
67
+ if (!caughtFirstError) {
68
+ // this is the first uncaught error and the ultimate reason for shutting down
69
+ // we want to do absolutely everything possible to ensure it gets captured
70
+ // also we want to make sure we don't go recursion crazy if more errors happen after this one
71
+ firstError = error;
72
+ caughtFirstError = true;
73
+
74
+ if (getClient() === client) {
75
+ captureException(error, {
76
+ originalException: error,
77
+ captureContext: {
78
+ level: 'fatal',
79
+ },
80
+ mechanism: {
81
+ handled: false,
82
+ type: 'onuncaughtexception',
83
+ },
84
+ });
85
+ }
86
+
87
+ if (!calledFatalError && shouldApplyFatalHandlingLogic) {
88
+ calledFatalError = true;
89
+ onFatalError(error);
90
+ }
91
+ } else {
92
+ if (shouldApplyFatalHandlingLogic) {
93
+ if (calledFatalError) {
94
+ // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down
95
+ DEBUG_BUILD &&
96
+ logger.warn(
97
+ 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown',
98
+ );
99
+ logAndExitProcess(error);
100
+ } else if (!caughtSecondError) {
101
+ // two cases for how we can hit this branch:
102
+ // - capturing of first error blew up and we just caught the exception from that
103
+ // - quit trying to capture, proceed with shutdown
104
+ // - a second independent error happened while waiting for first error to capture
105
+ // - want to avoid causing premature shutdown before first error capture finishes
106
+ // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff
107
+ // so let's instead just delay a bit before we proceed with our action here
108
+ // in case 1, we just wait a bit unnecessarily but ultimately do the same thing
109
+ // in case 2, the delay hopefully made us wait long enough for the capture to finish
110
+ // two potential nonideal outcomes:
111
+ // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError
112
+ // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error
113
+ // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError)
114
+ // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish
115
+ caughtSecondError = true;
116
+ setTimeout(() => {
117
+ if (!calledFatalError) {
118
+ // it was probably case 1, let's treat err as the sendErr and call onFatalError
119
+ calledFatalError = true;
120
+ onFatalError(firstError, error);
121
+ }
122
+ }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc
123
+ }
124
+ }
125
+ }
126
+ },
127
+ { _errorHandler: true },
128
+ );
129
+ }
130
+
131
+ export { makeErrorHandler, onUncaughtExceptionIntegration };
132
+ //# sourceMappingURL=onuncaughtexception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onuncaughtexception.js","sources":["../../../src/integrations/onuncaughtexception.ts"],"sourcesContent":["import { captureException, defineIntegration } from '@sentry/core';\nimport { getClient } from '@sentry/core';\nimport { logger } from '@sentry/utils';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { NodeClient } from '../sdk/client';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype OnFatalErrorHandler = (firstError: Error, secondError?: Error) => void;\n\ntype TaggedListener = NodeJS.UncaughtExceptionListener & {\n tag?: string;\n};\n\ninterface OnUncaughtExceptionOptions {\n /**\n * Controls if the SDK should register a handler to exit the process on uncaught errors:\n * - `true`: The SDK will exit the process on all uncaught errors.\n * - `false`: The SDK will only exit the process when there are no other `uncaughtException` handlers attached.\n *\n * Default: `false`\n */\n exitEvenIfOtherHandlersAreRegistered: boolean;\n\n /**\n * This is called when an uncaught error would cause the process to exit.\n *\n * @param firstError Uncaught error causing the process to exit\n * @param secondError Will be set if the handler was called multiple times. This can happen either because\n * `onFatalError` itself threw, or because an independent error happened somewhere else while `onFatalError`\n * was running.\n */\n onFatalError?(this: void, firstError: Error, secondError?: Error): void;\n}\n\nconst INTEGRATION_NAME = 'OnUncaughtException';\n\n/**\n * Add a global exception handler.\n */\nexport const onUncaughtExceptionIntegration = defineIntegration((options: Partial<OnUncaughtExceptionOptions> = {}) => {\n const optionsWithDefaults = {\n exitEvenIfOtherHandlersAreRegistered: false,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n global.process.on('uncaughtException', makeErrorHandler(client, optionsWithDefaults));\n },\n };\n});\n\ntype ErrorHandler = { _errorHandler: boolean } & ((error: Error) => void);\n\n/** Exported only for tests */\nexport function makeErrorHandler(client: NodeClient, options: OnUncaughtExceptionOptions): ErrorHandler {\n const timeout = 2000;\n let caughtFirstError: boolean = false;\n let caughtSecondError: boolean = false;\n let calledFatalError: boolean = false;\n let firstError: Error;\n\n const clientOptions = client.getOptions();\n\n return Object.assign(\n (error: Error): void => {\n let onFatalError: OnFatalErrorHandler = logAndExitProcess;\n\n if (options.onFatalError) {\n onFatalError = options.onFatalError;\n } else if (clientOptions.onFatalError) {\n onFatalError = clientOptions.onFatalError as OnFatalErrorHandler;\n }\n\n // Attaching a listener to `uncaughtException` will prevent the node process from exiting. We generally do not\n // want to alter this behaviour so we check for other listeners that users may have attached themselves and adjust\n // exit behaviour of the SDK accordingly:\n // - If other listeners are attached, do not exit.\n // - If the only listener attached is ours, exit.\n const userProvidedListenersCount = (global.process.listeners('uncaughtException') as TaggedListener[]).filter(\n listener => {\n // There are 3 listeners we ignore:\n return (\n // as soon as we're using domains this listener is attached by node itself\n listener.name !== 'domainUncaughtExceptionClear' &&\n // the handler we register for tracing\n listener.tag !== 'sentry_tracingErrorCallback' &&\n // the handler we register in this integration\n (listener as ErrorHandler)._errorHandler !== true\n );\n },\n ).length;\n\n const processWouldExit = userProvidedListenersCount === 0;\n const shouldApplyFatalHandlingLogic = options.exitEvenIfOtherHandlersAreRegistered || processWouldExit;\n\n if (!caughtFirstError) {\n // this is the first uncaught error and the ultimate reason for shutting down\n // we want to do absolutely everything possible to ensure it gets captured\n // also we want to make sure we don't go recursion crazy if more errors happen after this one\n firstError = error;\n caughtFirstError = true;\n\n if (getClient() === client) {\n captureException(error, {\n originalException: error,\n captureContext: {\n level: 'fatal',\n },\n mechanism: {\n handled: false,\n type: 'onuncaughtexception',\n },\n });\n }\n\n if (!calledFatalError && shouldApplyFatalHandlingLogic) {\n calledFatalError = true;\n onFatalError(error);\n }\n } else {\n if (shouldApplyFatalHandlingLogic) {\n if (calledFatalError) {\n // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down\n DEBUG_BUILD &&\n logger.warn(\n 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown',\n );\n logAndExitProcess(error);\n } else if (!caughtSecondError) {\n // two cases for how we can hit this branch:\n // - capturing of first error blew up and we just caught the exception from that\n // - quit trying to capture, proceed with shutdown\n // - a second independent error happened while waiting for first error to capture\n // - want to avoid causing premature shutdown before first error capture finishes\n // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff\n // so let's instead just delay a bit before we proceed with our action here\n // in case 1, we just wait a bit unnecessarily but ultimately do the same thing\n // in case 2, the delay hopefully made us wait long enough for the capture to finish\n // two potential nonideal outcomes:\n // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError\n // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error\n // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError)\n // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish\n caughtSecondError = true;\n setTimeout(() => {\n if (!calledFatalError) {\n // it was probably case 1, let's treat err as the sendErr and call onFatalError\n calledFatalError = true;\n onFatalError(firstError, error);\n } else {\n // it was probably case 2, our first error finished capturing while we waited, cool, do nothing\n }\n }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc\n }\n }\n }\n },\n { _errorHandler: true },\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { defineIntegration, getClient, captureException } from '@sentry/core';
2
+ import { consoleSandbox } from '@sentry/utils';
3
+ import { logAndExitProcess } from '../utils/errorhandling.js';
4
+
5
+ const INTEGRATION_NAME = 'OnUnhandledRejection';
6
+
7
+ const _onUnhandledRejectionIntegration = ((options = {}) => {
8
+ const mode = options.mode || 'warn';
9
+
10
+ return {
11
+ name: INTEGRATION_NAME,
12
+ setup(client) {
13
+ global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, { mode }));
14
+ },
15
+ };
16
+ }) ;
17
+
18
+ /**
19
+ * Add a global promise rejection handler.
20
+ */
21
+ const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);
22
+
23
+ /**
24
+ * Send an exception with reason
25
+ * @param reason string
26
+ * @param promise promise
27
+ *
28
+ * Exported only for tests.
29
+ */
30
+ function makeUnhandledPromiseHandler(
31
+ client,
32
+ options,
33
+ ) {
34
+ return function sendUnhandledPromise(reason, promise) {
35
+ if (getClient() !== client) {
36
+ return;
37
+ }
38
+
39
+ captureException(reason, {
40
+ originalException: promise,
41
+ captureContext: {
42
+ extra: { unhandledPromiseRejection: true },
43
+ },
44
+ mechanism: {
45
+ handled: false,
46
+ type: 'onunhandledrejection',
47
+ },
48
+ });
49
+
50
+ handleRejection(reason, options);
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Handler for `mode` option
56
+
57
+ */
58
+ function handleRejection(
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ reason,
61
+ options,
62
+ ) {
63
+ // https://github.com/nodejs/node/blob/7cf6f9e964aa00772965391c23acda6d71972a9a/lib/internal/process/promises.js#L234-L240
64
+ const rejectionWarning =
65
+ 'This error originated either by ' +
66
+ 'throwing inside of an async function without a catch block, ' +
67
+ 'or by rejecting a promise which was not handled with .catch().' +
68
+ ' The promise rejected with the reason:';
69
+
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
+
86
+ export { makeUnhandledPromiseHandler, onUnhandledRejectionIntegration };
87
+ //# sourceMappingURL=onunhandledrejection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onunhandledrejection.js","sources":["../../../src/integrations/onunhandledrejection.ts"],"sourcesContent":["import { captureException, defineIntegration, getClient } from '@sentry/core';\nimport type { Client, IntegrationFn } from '@sentry/types';\nimport { consoleSandbox } from '@sentry/utils';\nimport { logAndExitProcess } from '../utils/errorhandling';\n\ntype UnhandledRejectionMode = 'none' | 'warn' | 'strict';\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}\n\nconst INTEGRATION_NAME = 'OnUnhandledRejection';\n\nconst _onUnhandledRejectionIntegration = ((options: Partial<OnUnhandledRejectionOptions> = {}) => {\n const mode = options.mode || 'warn';\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n global.process.on('unhandledRejection', makeUnhandledPromiseHandler(client, { mode }));\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Add a global promise rejection handler.\n */\nexport const onUnhandledRejectionIntegration = defineIntegration(_onUnhandledRejectionIntegration);\n\n/**\n * Send an exception with reason\n * @param reason string\n * @param promise promise\n *\n * Exported only for tests.\n */\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 if (getClient() !== client) {\n return;\n }\n\n captureException(reason, {\n originalException: promise,\n captureContext: {\n extra: { unhandledPromiseRejection: true },\n },\n mechanism: {\n handled: false,\n type: 'onunhandledrejection',\n },\n });\n\n handleRejection(reason, options);\n };\n}\n\n/**\n * Handler for `mode` option\n\n */\nfunction handleRejection(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n reason: any,\n options: OnUnhandledRejectionOptions,\n): 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 (options.mode === 'warn') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n console.error(reason && reason.stack ? reason.stack : reason);\n });\n } else if (options.mode === 'strict') {\n consoleSandbox(() => {\n console.warn(rejectionWarning);\n });\n logAndExitProcess(reason);\n }\n /* eslint-enable no-console */\n}\n"],"names":[],"mappings":";;;;AAeA,MAAM,gBAAA,GAAmB,sBAAsB,CAAA;AAC/C;AACA,MAAM,gCAAA,IAAoC,CAAC,OAAO,GAAyC,EAAE,KAAK;AAClG,EAAE,MAAM,IAAK,GAAE,OAAO,CAAC,IAAA,IAAQ,MAAM,CAAA;AACrC;AACA,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,2BAA2B,CAAC,MAAM,EAAE,EAAE,IAAK,EAAC,CAAC,CAAC,CAAA;AAC5F,KAAK;AACL,GAAG,CAAA;AACH,CAAC,CAAE,EAAA;AACH;AACA;AACA;AACA;MACa,+BAAgC,GAAE,iBAAiB,CAAC,gCAAgC,EAAC;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,MAAM;AACR,EAAE,OAAO;AACT,EAA+C;AAC/C,EAAE,OAAO,SAAS,oBAAoB,CAAC,MAAM,EAAW,OAAO,EAAiB;AAChF,IAAI,IAAI,SAAS,EAAG,KAAI,MAAM,EAAE;AAChC,MAAM,OAAM;AACZ,KAAI;AACJ;AACA,IAAI,gBAAgB,CAAC,MAAM,EAAE;AAC7B,MAAM,iBAAiB,EAAE,OAAO;AAChC,MAAM,cAAc,EAAE;AACtB,QAAQ,KAAK,EAAE,EAAE,yBAAyB,EAAE,MAAM;AAClD,OAAO;AACP,MAAM,SAAS,EAAE;AACjB,QAAQ,OAAO,EAAE,KAAK;AACtB,QAAQ,IAAI,EAAE,sBAAsB;AACpC,OAAO;AACP,KAAK,CAAC,CAAA;AACN;AACA,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACpC,GAAG,CAAA;AACH,CAAA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe;AACxB;AACA,EAAE,MAAM;AACR,EAAE,OAAO;AACT,EAAQ;AACR;AACA,EAAE,MAAM,gBAAiB;AACzB,IAAI,kCAAmC;AACvC,IAAI,8DAA+D;AACnE,IAAI,gEAAiE;AACrE,IAAI,wCAAwC,CAAA;AAC5C;AACA;AACA,EAAE,IAAI,OAAO,CAAC,IAAK,KAAI,MAAM,EAAE;AAC/B,IAAI,cAAc,CAAC,MAAM;AACzB,MAAM,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;AACpC;AACA,MAAM,OAAO,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAA,GAAQ,MAAM,CAAC,KAAM,GAAE,MAAM,CAAC,CAAA;AACnE,KAAK,CAAC,CAAA;AACN,GAAE,MAAO,IAAI,OAAO,CAAC,IAAA,KAAS,QAAQ,EAAE;AACxC,IAAI,cAAc,CAAC,MAAM;AACzB,MAAM,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;AACpC,KAAK,CAAC,CAAA;AACN,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAA;AAC7B,GAAE;AACF;AACA;;;;"}
@@ -0,0 +1,106 @@
1
+ import * as http from 'http';
2
+ import { defineIntegration } from '@sentry/core';
3
+ import { logger, serializeEnvelope } from '@sentry/utils';
4
+
5
+ const INTEGRATION_NAME = 'Spotlight';
6
+
7
+ const _spotlightIntegration = ((options = {}) => {
8
+ const _options = {
9
+ sidecarUrl: options.sidecarUrl || 'http://localhost:8969/stream',
10
+ };
11
+
12
+ return {
13
+ name: INTEGRATION_NAME,
14
+ setup(client) {
15
+ if (typeof process === 'object' && process.env && process.env.NODE_ENV !== 'development') {
16
+ logger.warn("[Spotlight] It seems you're not in dev mode. Do you really want to have Spotlight enabled?");
17
+ }
18
+ connectToSpotlight(client, _options);
19
+ },
20
+ };
21
+ }) ;
22
+
23
+ /**
24
+ * Use this integration to send errors and transactions to Spotlight.
25
+ *
26
+ * Learn more about spotlight at https://spotlightjs.com
27
+ *
28
+ * Important: This integration only works with Node 18 or newer.
29
+ */
30
+ const spotlightIntegration = defineIntegration(_spotlightIntegration);
31
+
32
+ function connectToSpotlight(client, options) {
33
+ const spotlightUrl = parseSidecarUrl(options.sidecarUrl);
34
+ if (!spotlightUrl) {
35
+ return;
36
+ }
37
+
38
+ let failedRequests = 0;
39
+
40
+ client.on('beforeEnvelope', (envelope) => {
41
+ if (failedRequests > 3) {
42
+ logger.warn('[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests');
43
+ return;
44
+ }
45
+
46
+ const serializedEnvelope = serializeEnvelope(envelope);
47
+
48
+ const request = getNativeHttpRequest();
49
+ const req = request(
50
+ {
51
+ method: 'POST',
52
+ path: spotlightUrl.pathname,
53
+ hostname: spotlightUrl.hostname,
54
+ port: spotlightUrl.port,
55
+ headers: {
56
+ 'Content-Type': 'application/x-sentry-envelope',
57
+ },
58
+ },
59
+ res => {
60
+ res.on('data', () => {
61
+ // Drain socket
62
+ });
63
+
64
+ res.on('end', () => {
65
+ // Drain socket
66
+ });
67
+ res.setEncoding('utf8');
68
+ },
69
+ );
70
+
71
+ req.on('error', () => {
72
+ failedRequests++;
73
+ logger.warn('[Spotlight] Failed to send envelope to Spotlight Sidecar');
74
+ });
75
+ req.write(serializedEnvelope);
76
+ req.end();
77
+ });
78
+ }
79
+
80
+ function parseSidecarUrl(url) {
81
+ try {
82
+ return new URL(`${url}`);
83
+ } catch (e) {
84
+ logger.warn(`[Spotlight] Invalid sidecar URL: ${url}`);
85
+ return undefined;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * We want to get an unpatched http request implementation to avoid capturing our own calls.
91
+ */
92
+ function getNativeHttpRequest() {
93
+ const { request } = http;
94
+ if (isWrapped(request)) {
95
+ return request.__sentry_original__;
96
+ }
97
+
98
+ return request;
99
+ }
100
+
101
+ function isWrapped(impl) {
102
+ return '__sentry_original__' in impl;
103
+ }
104
+
105
+ export { getNativeHttpRequest, spotlightIntegration };
106
+ //# sourceMappingURL=spotlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spotlight.js","sources":["../../../src/integrations/spotlight.ts"],"sourcesContent":["import * as http from 'http';\nimport { defineIntegration } from '@sentry/core';\nimport type { Client, Envelope, IntegrationFn } from '@sentry/types';\nimport { logger, serializeEnvelope } from '@sentry/utils';\n\ntype SpotlightConnectionOptions = {\n /**\n * Set this if the Spotlight Sidecar is not running on localhost:8969\n * By default, the Url is set to http://localhost:8969/stream\n */\n sidecarUrl?: string;\n};\n\nconst INTEGRATION_NAME = 'Spotlight';\n\nconst _spotlightIntegration = ((options: Partial<SpotlightConnectionOptions> = {}) => {\n const _options = {\n sidecarUrl: options.sidecarUrl || 'http://localhost:8969/stream',\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n if (typeof process === 'object' && process.env && process.env.NODE_ENV !== 'development') {\n logger.warn(\"[Spotlight] It seems you're not in dev mode. Do you really want to have Spotlight enabled?\");\n }\n connectToSpotlight(client, _options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Use this integration to send errors and transactions to Spotlight.\n *\n * Learn more about spotlight at https://spotlightjs.com\n *\n * Important: This integration only works with Node 18 or newer.\n */\nexport const spotlightIntegration = defineIntegration(_spotlightIntegration);\n\nfunction connectToSpotlight(client: Client, options: Required<SpotlightConnectionOptions>): void {\n const spotlightUrl = parseSidecarUrl(options.sidecarUrl);\n if (!spotlightUrl) {\n return;\n }\n\n let failedRequests = 0;\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (failedRequests > 3) {\n logger.warn('[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests');\n return;\n }\n\n const serializedEnvelope = serializeEnvelope(envelope);\n\n const request = getNativeHttpRequest();\n const req = request(\n {\n method: 'POST',\n path: spotlightUrl.pathname,\n hostname: spotlightUrl.hostname,\n port: spotlightUrl.port,\n headers: {\n 'Content-Type': 'application/x-sentry-envelope',\n },\n },\n res => {\n res.on('data', () => {\n // Drain socket\n });\n\n res.on('end', () => {\n // Drain socket\n });\n res.setEncoding('utf8');\n },\n );\n\n req.on('error', () => {\n failedRequests++;\n logger.warn('[Spotlight] Failed to send envelope to Spotlight Sidecar');\n });\n req.write(serializedEnvelope);\n req.end();\n });\n}\n\nfunction parseSidecarUrl(url: string): URL | undefined {\n try {\n return new URL(`${url}`);\n } catch {\n logger.warn(`[Spotlight] Invalid sidecar URL: ${url}`);\n return undefined;\n }\n}\n\ntype HttpRequestImpl = typeof http.request;\ntype WrappedHttpRequest = HttpRequestImpl & { __sentry_original__: HttpRequestImpl };\n\n/**\n * We want to get an unpatched http request implementation to avoid capturing our own calls.\n */\nexport function getNativeHttpRequest(): HttpRequestImpl {\n const { request } = http;\n if (isWrapped(request)) {\n return request.__sentry_original__;\n }\n\n return request;\n}\n\nfunction isWrapped(impl: HttpRequestImpl): impl is WrappedHttpRequest {\n return '__sentry_original__' in impl;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { isWrapped } from '@opentelemetry/core';
2
+ import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';
3
+ import { defineIntegration, isEnabled, captureException } from '@sentry/core';
4
+ import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';
5
+ import { consoleSandbox } from '@sentry/utils';
6
+
7
+ const _connectIntegration = (() => {
8
+ return {
9
+ name: 'Connect',
10
+ setupOnce() {
11
+ addOpenTelemetryInstrumentation(new ConnectInstrumentation({}));
12
+ },
13
+ };
14
+ }) ;
15
+
16
+ const connectIntegration = defineIntegration(_connectIntegration);
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ function connectErrorMiddleware(err, req, res, next) {
20
+ captureException(err);
21
+ next(err);
22
+ }
23
+
24
+ const setupConnectErrorHandler = (app) => {
25
+ app.use(connectErrorMiddleware);
26
+
27
+ if (!isWrapped(app.use) && isEnabled()) {
28
+ consoleSandbox(() => {
29
+ // eslint-disable-next-line no-console
30
+ console.warn(
31
+ '[Sentry] Connect is not instrumented. This is likely because you required/imported connect before calling `Sentry.init()`.',
32
+ );
33
+ });
34
+ }
35
+ };
36
+
37
+ export { connectIntegration, setupConnectErrorHandler };
38
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sources":["../../../../src/integrations/tracing/connect.ts"],"sourcesContent":["import { isWrapped } from '@opentelemetry/core';\nimport { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect';\nimport { captureException, defineIntegration, isEnabled } from '@sentry/core';\nimport { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';\nimport type { IntegrationFn } from '@sentry/types';\nimport { consoleSandbox } from '@sentry/utils';\n\ntype ConnectApp = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n use: (middleware: any) => void;\n};\n\nconst _connectIntegration = (() => {\n return {\n name: 'Connect',\n setupOnce() {\n addOpenTelemetryInstrumentation(new ConnectInstrumentation({}));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const connectIntegration = defineIntegration(_connectIntegration);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction connectErrorMiddleware(err: any, req: any, res: any, next: any): void {\n captureException(err);\n next(err);\n}\n\nexport const setupConnectErrorHandler = (app: ConnectApp): void => {\n app.use(connectErrorMiddleware);\n\n if (!isWrapped(app.use) && isEnabled()) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Connect is not instrumented. This is likely because you required/imported connect before calling `Sentry.init()`.',\n );\n });\n }\n};\n"],"names":[],"mappings":";;;;;;AAYA,MAAM,mBAAoB,IAAG,MAAM;AACnC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,SAAS;AACnB,IAAI,SAAS,GAAG;AAChB,MAAM,+BAA+B,CAAC,IAAI,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAA;AACrE,KAAK;AACL,GAAG,CAAA;AACH,CAAC,CAAE,EAAA;AACH;MACa,kBAAmB,GAAE,iBAAiB,CAAC,mBAAmB,EAAC;AACxE;AACA;AACA,SAAS,sBAAsB,CAAC,GAAG,EAAO,GAAG,EAAO,GAAG,EAAO,IAAI,EAAa;AAC/E,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAA;AACvB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;AACX,CAAA;AACA;AACa,MAAA,wBAAA,GAA2B,CAAC,GAAG,KAAuB;AACnE,EAAE,GAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAA;AACjC;AACA,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAE,IAAG,SAAS,EAAE,EAAE;AAC1C,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,IAAI;AAClB,QAAQ,4HAA4H;AACpI,OAAO,CAAA;AACP,KAAK,CAAC,CAAA;AACN,GAAE;AACF;;;;"}
@@ -0,0 +1,120 @@
1
+ import { _optionalChain } from '@sentry/utils';
2
+ import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
3
+ import { defineIntegration, getIsolationScope, getDefaultIsolationScope, getClient, captureException, isEnabled } from '@sentry/core';
4
+ import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry';
5
+ import { isWrapped } from '@opentelemetry/core';
6
+ import { logger, consoleSandbox } from '@sentry/utils';
7
+ import { DEBUG_BUILD } from '../../debug-build.js';
8
+ import { addOriginToSpan } from '../../utils/addOriginToSpan.js';
9
+
10
+ const _expressIntegration = (() => {
11
+ return {
12
+ name: 'Express',
13
+ setupOnce() {
14
+ addOpenTelemetryInstrumentation(
15
+ new ExpressInstrumentation({
16
+ requestHook(span) {
17
+ addOriginToSpan(span, 'auto.http.otel.express');
18
+ },
19
+ spanNameHook(info, defaultName) {
20
+ if (getIsolationScope() === getDefaultIsolationScope()) {
21
+ DEBUG_BUILD &&
22
+ logger.warn('Isolation scope is still default isolation scope - skipping setting transactionName');
23
+ return defaultName;
24
+ }
25
+ if (info.layerType === 'request_handler') {
26
+ // type cast b/c Otel unfortunately types info.request as any :(
27
+ const req = info.request ;
28
+ const method = req.method ? req.method.toUpperCase() : 'GET';
29
+ getIsolationScope().setTransactionName(`${method} ${info.route}`);
30
+ }
31
+ return defaultName;
32
+ },
33
+ }),
34
+ );
35
+ },
36
+ };
37
+ }) ;
38
+
39
+ /**
40
+ * Express integration
41
+ *
42
+ * Capture tracing data for express.
43
+ * In order to capture exceptions, you have to call `setupExpressErrorHandler(app)` before any other middleware and after all controllers.
44
+ */
45
+ const expressIntegration = defineIntegration(_expressIntegration);
46
+
47
+ /**
48
+ * An Express-compatible error handler.
49
+ */
50
+ function expressErrorHandler(options
51
+
52
+ ) {
53
+ return function sentryErrorMiddleware(
54
+ error,
55
+ _req,
56
+ res,
57
+ next,
58
+ ) {
59
+ const shouldHandleError = _optionalChain([options, 'optionalAccess', _ => _.shouldHandleError]) || defaultShouldHandleError;
60
+
61
+ if (shouldHandleError(error)) {
62
+ const client = getClient();
63
+ if (client && client.getOptions().autoSessionTracking) {
64
+ // Check if the `SessionFlusher` is instantiated on the client to go into this branch that marks the
65
+ // `requestSession.status` as `Crashed`, and this check is necessary because the `SessionFlusher` is only
66
+ // instantiated when the the`requestHandler` middleware is initialised, which indicates that we should be
67
+ // running in SessionAggregates mode
68
+ const isSessionAggregatesMode = client['_sessionFlusher'] !== undefined;
69
+ if (isSessionAggregatesMode) {
70
+ const requestSession = getIsolationScope().getRequestSession();
71
+ // If an error bubbles to the `errorHandler`, then this is an unhandled error, and should be reported as a
72
+ // Crashed session. The `_requestSession.status` is checked to ensure that this error is happening within
73
+ // the bounds of a request, and if so the status is updated
74
+ if (requestSession && requestSession.status !== undefined) {
75
+ requestSession.status = 'crashed';
76
+ }
77
+ }
78
+ }
79
+
80
+ const eventId = captureException(error, { mechanism: { type: 'middleware', handled: false } });
81
+ (res ).sentry = eventId;
82
+ next(error);
83
+
84
+ return;
85
+ }
86
+
87
+ next(error);
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Setup an error handler for Express.
93
+ * The error handler must be before any other middleware and after all controllers.
94
+ */
95
+ function setupExpressErrorHandler(app) {
96
+ app.use(expressErrorHandler());
97
+
98
+ if (!isWrapped(app.use) && isEnabled()) {
99
+ consoleSandbox(() => {
100
+ // eslint-disable-next-line no-console
101
+ console.warn(
102
+ '[Sentry] Express is not instrumented. This is likely because you required/imported express before calling `Sentry.init()`.',
103
+ );
104
+ });
105
+ }
106
+ }
107
+
108
+ function getStatusCodeFromResponse(error) {
109
+ const statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode);
110
+ return statusCode ? parseInt(statusCode , 10) : 500;
111
+ }
112
+
113
+ /** Returns true if response code is internal server error */
114
+ function defaultShouldHandleError(error) {
115
+ const status = getStatusCodeFromResponse(error);
116
+ return status >= 500;
117
+ }
118
+
119
+ export { expressErrorHandler, expressIntegration, setupExpressErrorHandler };
120
+ //# sourceMappingURL=express.js.map