@prairielearn/sentry 2.0.2 → 2.0.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @prairielearn/sentry
2
2
 
3
+ ## 2.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 68653a6: Handle errors inside request event processor
8
+
9
+ ## 2.0.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 24a93b8: Upgrade all JavaScript dependencies
14
+
3
15
  ## 2.0.2
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -4,5 +4,19 @@ import * as Sentry from '@sentry/node';
4
4
  * based on the current Git revision.
5
5
  */
6
6
  export declare function init(options: Sentry.NodeOptions): Promise<void>;
7
- export { Breadcrumb, BreadcrumbHint, Request, SdkInfo, Event, EventHint, Exception, Session, Severity, SeverityLevel, StackFrame, Stacktrace, Thread, User, AddRequestDataToEventOptions, PolymorphicRequest, NodeOptions, } from '@sentry/node';
8
- export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, createTransport, getHubFromCarrier, getCurrentHub, Hub, makeMain, Scope, startTransaction, SDK_VERSION, setContext, setExtra, setExtras, setTag, setTags, setUser, withScope, NodeClient, makeNodeTransport, addRequestDataToEvent, extractRequestData, defaultIntegrations, defaultStackParser, lastEventId, flush, close, getSentryRelease, deepReadDirSync, Integrations, Handlers, runWithAsyncContext, getCurrentScope, } from '@sentry/node';
7
+ /**
8
+ * Sentry v8 switched from simple, manual instrumentation to "automatic"
9
+ * instrumentation based on OpenTelemetry. However, this interferes with
10
+ * the way that our applications asynchronously load their configuration,
11
+ * specifically the Sentry DSN. Sentry's automatic request isolation and
12
+ * request data extraction requires that `Sentry.init` be called before
13
+ * any other code is loaded, but our application startup structure is such
14
+ * that we import most of our own code before we can load the Sentry DSN.
15
+ *
16
+ * Rather than jumping through hoops to restructure our application to
17
+ * support this, this small function can be added as Express middleware to
18
+ * isolate requests and set request data for Sentry.
19
+ */
20
+ export declare function requestHandler(): (req: any, _res: any, next: any) => void;
21
+ export { Breadcrumb, BreadcrumbHint, Request, PolymorphicRequest, SdkInfo, Event, EventHint, Exception, Session, SeverityLevel, StackFrame, Stacktrace, Thread, User, Span, NodeOptions, } from '@sentry/node';
22
+ export { addEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, createTransport, getCurrentHub, Scope, SDK_VERSION, setContext, setExtra, setExtras, setTag, setTags, setUser, withScope, NodeClient, makeNodeTransport, addRequestDataToEvent, extractRequestData, defaultStackParser, flush, close, getSentryRelease, getCurrentScope, startSpan, startSpanManual, startInactiveSpan, expressIntegration, expressErrorHandler, setupExpressErrorHandler, } from '@sentry/node';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Sentry from '@sentry/node';
2
+ import { stripUrlQueryAndFragment } from '@sentry/utils';
2
3
  import { execa } from 'execa';
3
4
  /**
4
5
  * A thin wrapper around {@link Sentry.init} that automatically sets `release`
@@ -20,5 +21,57 @@ export async function init(options) {
20
21
  ...options,
21
22
  });
22
23
  }
23
- export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, createTransport, getHubFromCarrier, getCurrentHub, Hub, makeMain, Scope, startTransaction, SDK_VERSION, setContext, setExtra, setExtras, setTag, setTags, setUser, withScope, NodeClient, makeNodeTransport, addRequestDataToEvent, extractRequestData, defaultIntegrations, defaultStackParser, lastEventId, flush, close, getSentryRelease, deepReadDirSync, Integrations, Handlers, runWithAsyncContext, getCurrentScope, } from '@sentry/node';
24
+ /**
25
+ * Based on Sentry code that is not exported:
26
+ * https://github.com/getsentry/sentry-javascript/blob/602703652959b581304a7849cb97117f296493bc/packages/utils/src/requestdata.ts#L102
27
+ */
28
+ function extractTransaction(req) {
29
+ const method = req.method?.toUpperCase() || '';
30
+ const path = stripUrlQueryAndFragment(req.originalUrl || req.url || '');
31
+ let name = '';
32
+ if (method) {
33
+ name += method;
34
+ }
35
+ if (method && path) {
36
+ name += ' ';
37
+ }
38
+ if (path) {
39
+ name += path;
40
+ }
41
+ return name;
42
+ }
43
+ /**
44
+ * Sentry v8 switched from simple, manual instrumentation to "automatic"
45
+ * instrumentation based on OpenTelemetry. However, this interferes with
46
+ * the way that our applications asynchronously load their configuration,
47
+ * specifically the Sentry DSN. Sentry's automatic request isolation and
48
+ * request data extraction requires that `Sentry.init` be called before
49
+ * any other code is loaded, but our application startup structure is such
50
+ * that we import most of our own code before we can load the Sentry DSN.
51
+ *
52
+ * Rather than jumping through hoops to restructure our application to
53
+ * support this, this small function can be added as Express middleware to
54
+ * isolate requests and set request data for Sentry.
55
+ */
56
+ export function requestHandler() {
57
+ return (req, _res, next) => {
58
+ Sentry.withIsolationScope((scope) => {
59
+ scope.addEventProcessor((event) => {
60
+ // If an event processor throws an error, Sentry will catch it and
61
+ // retrigger the event processor, which infinitely recurses. We'll
62
+ // treat our event processor as a best-effort operation and silently
63
+ // swallow any errors.
64
+ try {
65
+ event.transaction = extractTransaction(req);
66
+ return Sentry.addRequestDataToEvent(event, req);
67
+ }
68
+ catch {
69
+ return event;
70
+ }
71
+ });
72
+ next();
73
+ });
74
+ };
75
+ }
76
+ export { addEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, createTransport, getCurrentHub, Scope, SDK_VERSION, setContext, setExtra, setExtras, setTag, setTags, setUser, withScope, NodeClient, makeNodeTransport, addRequestDataToEvent, extractRequestData, defaultStackParser, flush, close, getSentryRelease, getCurrentScope, startSpan, startSpanManual, startInactiveSpan, expressIntegration, expressErrorHandler, setupExpressErrorHandler, } from '@sentry/node';
24
77
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAA2B;IACpD,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAE9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mEAAmE;YACnE,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC;QACV,OAAO;QACP,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAyBD,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,GAAG,EACH,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,KAAK,EACL,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,mBAAmB,EACnB,eAAe,GAChB,MAAM,cAAc,CAAC","sourcesContent":["import * as Sentry from '@sentry/node';\nimport { execa } from 'execa';\n\n/**\n * A thin wrapper around {@link Sentry.init} that automatically sets `release`\n * based on the current Git revision.\n */\nexport async function init(options: Sentry.NodeOptions) {\n let release = options.release;\n\n if (!release) {\n try {\n release = (await execa('git', ['rev-parse', 'HEAD'])).stdout.trim();\n } catch (e) {\n // This most likely isn't running in an initialized git repository.\n // Default to not setting a release.\n }\n }\n\n Sentry.init({\n release,\n ...options,\n });\n}\n\n// We export every type and function from `@sentry/node` *except* for init,\n// which we replace with our own version up above.\n\nexport {\n Breadcrumb,\n BreadcrumbHint,\n Request,\n SdkInfo,\n Event,\n EventHint,\n Exception,\n Session,\n Severity,\n SeverityLevel,\n StackFrame,\n Stacktrace,\n Thread,\n User,\n AddRequestDataToEventOptions,\n PolymorphicRequest,\n NodeOptions,\n} from '@sentry/node';\n\nexport {\n addGlobalEventProcessor,\n addBreadcrumb,\n captureException,\n captureEvent,\n captureMessage,\n configureScope,\n createTransport,\n getHubFromCarrier,\n getCurrentHub,\n Hub,\n makeMain,\n Scope,\n startTransaction,\n SDK_VERSION,\n setContext,\n setExtra,\n setExtras,\n setTag,\n setTags,\n setUser,\n withScope,\n NodeClient,\n makeNodeTransport,\n addRequestDataToEvent,\n extractRequestData,\n defaultIntegrations,\n defaultStackParser,\n lastEventId,\n flush,\n close,\n getSentryRelease,\n deepReadDirSync,\n Integrations,\n Handlers,\n runWithAsyncContext,\n getCurrentScope,\n} from '@sentry/node';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAA2B;IACpD,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAE9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,mEAAmE;YACnE,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC;QACV,OAAO;QACP,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,GAAQ;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,wBAAwB,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAExE,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,IAAI,MAAM,CAAC;IACjB,CAAC;IACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,IAAI,IAAI,GAAG,CAAC;IACd,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,IAAI,IAAI,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAQ,EAAE,IAAS,EAAE,IAAS,EAAE,EAAE;QACxC,MAAM,CAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE;YAClC,KAAK,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChC,kEAAkE;gBAClE,kEAAkE;gBAClE,oEAAoE;gBACpE,sBAAsB;gBACtB,IAAI,CAAC;oBACH,KAAK,CAAC,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;oBAC5C,OAAO,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAClD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAwBD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,aAAa,EACb,KAAK,EACL,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,EACL,KAAK,EACL,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,cAAc,CAAC","sourcesContent":["import * as Sentry from '@sentry/node';\nimport { stripUrlQueryAndFragment } from '@sentry/utils';\nimport { execa } from 'execa';\n\n/**\n * A thin wrapper around {@link Sentry.init} that automatically sets `release`\n * based on the current Git revision.\n */\nexport async function init(options: Sentry.NodeOptions) {\n let release = options.release;\n\n if (!release) {\n try {\n release = (await execa('git', ['rev-parse', 'HEAD'])).stdout.trim();\n } catch (e) {\n // This most likely isn't running in an initialized git repository.\n // Default to not setting a release.\n }\n }\n\n Sentry.init({\n release,\n ...options,\n });\n}\n\n/**\n * Based on Sentry code that is not exported:\n * https://github.com/getsentry/sentry-javascript/blob/602703652959b581304a7849cb97117f296493bc/packages/utils/src/requestdata.ts#L102\n */\nfunction extractTransaction(req: any) {\n const method = req.method?.toUpperCase() || '';\n const path = stripUrlQueryAndFragment(req.originalUrl || req.url || '');\n\n let name = '';\n if (method) {\n name += method;\n }\n if (method && path) {\n name += ' ';\n }\n if (path) {\n name += path;\n }\n\n return name;\n}\n\n/**\n * Sentry v8 switched from simple, manual instrumentation to \"automatic\"\n * instrumentation based on OpenTelemetry. However, this interferes with\n * the way that our applications asynchronously load their configuration,\n * specifically the Sentry DSN. Sentry's automatic request isolation and\n * request data extraction requires that `Sentry.init` be called before\n * any other code is loaded, but our application startup structure is such\n * that we import most of our own code before we can load the Sentry DSN.\n *\n * Rather than jumping through hoops to restructure our application to\n * support this, this small function can be added as Express middleware to\n * isolate requests and set request data for Sentry.\n */\nexport function requestHandler() {\n return (req: any, _res: any, next: any) => {\n Sentry.withIsolationScope((scope) => {\n scope.addEventProcessor((event) => {\n // If an event processor throws an error, Sentry will catch it and\n // retrigger the event processor, which infinitely recurses. We'll\n // treat our event processor as a best-effort operation and silently\n // swallow any errors.\n try {\n event.transaction = extractTransaction(req);\n return Sentry.addRequestDataToEvent(event, req);\n } catch {\n return event;\n }\n });\n\n next();\n });\n };\n}\n\n// We export every type and function from `@sentry/node` *except* for init,\n// which we replace with our own version up above.\n\nexport {\n Breadcrumb,\n BreadcrumbHint,\n Request,\n PolymorphicRequest,\n SdkInfo,\n Event,\n EventHint,\n Exception,\n Session,\n SeverityLevel,\n StackFrame,\n Stacktrace,\n Thread,\n User,\n Span,\n NodeOptions,\n} from '@sentry/node';\n\nexport {\n addEventProcessor,\n addBreadcrumb,\n captureException,\n captureEvent,\n captureMessage,\n createTransport,\n getCurrentHub,\n Scope,\n SDK_VERSION,\n setContext,\n setExtra,\n setExtras,\n setTag,\n setTags,\n setUser,\n withScope,\n NodeClient,\n makeNodeTransport,\n addRequestDataToEvent,\n extractRequestData,\n defaultStackParser,\n flush,\n close,\n getSentryRelease,\n getCurrentScope,\n startSpan,\n startSpanManual,\n startInactiveSpan,\n expressIntegration,\n expressErrorHandler,\n setupExpressErrorHandler,\n} from '@sentry/node';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prairielearn/sentry",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "repository": {
@@ -14,12 +14,13 @@
14
14
  },
15
15
  "devDependencies": {
16
16
  "@prairielearn/tsconfig": "^0.0.0",
17
- "@types/node": "^20.13.0",
18
- "tsx": "^4.11.0",
19
- "typescript": "^5.4.5"
17
+ "@types/node": "^20.14.9",
18
+ "tsx": "^4.16.2",
19
+ "typescript": "^5.5.3"
20
20
  },
21
21
  "dependencies": {
22
- "@sentry/node": "^7.116.0",
23
- "execa": "^9.1.0"
22
+ "@sentry/node": "^8.18.0",
23
+ "@sentry/utils": "^8.18.0",
24
+ "execa": "^9.3.0"
24
25
  }
25
26
  }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Sentry from '@sentry/node';
2
+ import { stripUrlQueryAndFragment } from '@sentry/utils';
2
3
  import { execa } from 'execa';
3
4
 
4
5
  /**
@@ -23,6 +24,62 @@ export async function init(options: Sentry.NodeOptions) {
23
24
  });
24
25
  }
25
26
 
27
+ /**
28
+ * Based on Sentry code that is not exported:
29
+ * https://github.com/getsentry/sentry-javascript/blob/602703652959b581304a7849cb97117f296493bc/packages/utils/src/requestdata.ts#L102
30
+ */
31
+ function extractTransaction(req: any) {
32
+ const method = req.method?.toUpperCase() || '';
33
+ const path = stripUrlQueryAndFragment(req.originalUrl || req.url || '');
34
+
35
+ let name = '';
36
+ if (method) {
37
+ name += method;
38
+ }
39
+ if (method && path) {
40
+ name += ' ';
41
+ }
42
+ if (path) {
43
+ name += path;
44
+ }
45
+
46
+ return name;
47
+ }
48
+
49
+ /**
50
+ * Sentry v8 switched from simple, manual instrumentation to "automatic"
51
+ * instrumentation based on OpenTelemetry. However, this interferes with
52
+ * the way that our applications asynchronously load their configuration,
53
+ * specifically the Sentry DSN. Sentry's automatic request isolation and
54
+ * request data extraction requires that `Sentry.init` be called before
55
+ * any other code is loaded, but our application startup structure is such
56
+ * that we import most of our own code before we can load the Sentry DSN.
57
+ *
58
+ * Rather than jumping through hoops to restructure our application to
59
+ * support this, this small function can be added as Express middleware to
60
+ * isolate requests and set request data for Sentry.
61
+ */
62
+ export function requestHandler() {
63
+ return (req: any, _res: any, next: any) => {
64
+ Sentry.withIsolationScope((scope) => {
65
+ scope.addEventProcessor((event) => {
66
+ // If an event processor throws an error, Sentry will catch it and
67
+ // retrigger the event processor, which infinitely recurses. We'll
68
+ // treat our event processor as a best-effort operation and silently
69
+ // swallow any errors.
70
+ try {
71
+ event.transaction = extractTransaction(req);
72
+ return Sentry.addRequestDataToEvent(event, req);
73
+ } catch {
74
+ return event;
75
+ }
76
+ });
77
+
78
+ next();
79
+ });
80
+ };
81
+ }
82
+
26
83
  // We export every type and function from `@sentry/node` *except* for init,
27
84
  // which we replace with our own version up above.
28
85
 
@@ -30,36 +87,30 @@ export {
30
87
  Breadcrumb,
31
88
  BreadcrumbHint,
32
89
  Request,
90
+ PolymorphicRequest,
33
91
  SdkInfo,
34
92
  Event,
35
93
  EventHint,
36
94
  Exception,
37
95
  Session,
38
- Severity,
39
96
  SeverityLevel,
40
97
  StackFrame,
41
98
  Stacktrace,
42
99
  Thread,
43
100
  User,
44
- AddRequestDataToEventOptions,
45
- PolymorphicRequest,
101
+ Span,
46
102
  NodeOptions,
47
103
  } from '@sentry/node';
48
104
 
49
105
  export {
50
- addGlobalEventProcessor,
106
+ addEventProcessor,
51
107
  addBreadcrumb,
52
108
  captureException,
53
109
  captureEvent,
54
110
  captureMessage,
55
- configureScope,
56
111
  createTransport,
57
- getHubFromCarrier,
58
112
  getCurrentHub,
59
- Hub,
60
- makeMain,
61
113
  Scope,
62
- startTransaction,
63
114
  SDK_VERSION,
64
115
  setContext,
65
116
  setExtra,
@@ -72,15 +123,15 @@ export {
72
123
  makeNodeTransport,
73
124
  addRequestDataToEvent,
74
125
  extractRequestData,
75
- defaultIntegrations,
76
126
  defaultStackParser,
77
- lastEventId,
78
127
  flush,
79
128
  close,
80
129
  getSentryRelease,
81
- deepReadDirSync,
82
- Integrations,
83
- Handlers,
84
- runWithAsyncContext,
85
130
  getCurrentScope,
131
+ startSpan,
132
+ startSpanManual,
133
+ startInactiveSpan,
134
+ expressIntegration,
135
+ expressErrorHandler,
136
+ setupExpressErrorHandler,
86
137
  } from '@sentry/node';