@@ -8,6 +8,24 @@ import type { Handle, ResolveOptions } from '@sveltejs/kit';
8
8
import { isHttpError, isRedirect } from '../common/utils';
9
9
import { getTracePropagationData } from './utils';
10
10
11
+ export type SentryHandleOptions = {
12
+ /**
13
+ * Controls whether the SDK should capture errors and traces in requests that don't belong to a
14
+ * route defined in your SvelteKit application.
15
+ *
16
+ * By default, this option is set to `false` to reduce noise (e.g. bots sending random requests to your server).
17
+ *
18
+ * Set this option to `true` if you want to monitor requests events without a route. This might be useful in certain
19
+ * scenarios, for instance if you registered other handlers that handle these requests.
20
+ * If you set this option, you might want adjust the the transaction name in the `beforeSendTransaction`
21
+ * callback of your server-side `Sentry.init` options. You can also use `beforeSendTransaction` to filter out
22
+ * transactions that you still don't want to be sent to Sentry.
23
+ *
24
+ * @default false
25
+ */
26
+ handleUnknownRoutes?: boolean;
27
+ };
28
+
11
29
function sendErrorToSentry(e: unknown): unknown {
12
30
// In case we have a primitive, wrap it in the equivalent wrapper class (string -> String, etc.) so that we can
13
31
// store a seen flag on it.
@@ -68,33 +86,42 @@ export const transformPageChunk: NonNullable<ResolveOptions['transformPageChunk'
68
86
* // export const handle = sequence(sentryHandle(), yourCustomHandler);
69
87
* ```
70
88
*/
71
- export function sentryHandle(): Handle {
89
+ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle {
90
+ const options = {
91
+ handleUnknownRoutes: false,
92
+ ...handlerOptions,
93
+ };
94
+
95
+ const sentryRequestHandler: Handle = input => {
96
+ // if there is an active transaction, we know that this handle call is nested and hence
97
+ // we don't create a new domain for it. If we created one, nested server calls would
98
+ // create new transactions instead of adding a child span to the currently active span.
99
+ if (getCurrentHub().getScope().getSpan()) {
100
+ return instrumentHandle(input, options);
101
+ }
102
+ return runWithAsyncContext(() => {
103
+ return instrumentHandle(input, options);
104
+ });
105
+ };
106
+
72
107
return sentryRequestHandler;
73
108
}
74
109
75
- const sentryRequestHandler: Handle = input => {
76
- // if there is an active transaction, we know that this handle call is nested and hence
77
- // we don't create a new domain for it. If we created one, nested server calls would
78
- // create new transactions instead of adding a child span to the currently active span.
79
- if (getCurrentHub().getScope().getSpan()) {
80
- return instrumentHandle(input);
110
+ function instrumentHandle({ event, resolve }: Parameters<Handle>[0], options: SentryHandleOptions): ReturnType<Handle> {
111
+ if (!event.route?.id && !options.handleUnknownRoutes) {
112
+ return resolve(event);
81
113
}
82
- return runWithAsyncContext(() => {
83
- return instrumentHandle(input);
84
- });
85
- };
86
114
87
- function instrumentHandle({ event, resolve }: Parameters<Handle>[0]): ReturnType<Handle> {
88
115
const { traceparentData, dynamicSamplingContext } = getTracePropagationData(event);
89
116
90
117
return trace(
91
118
{
92
119
op: 'http.server',
93
- name: `${event.request.method} ${event.route.id}`,
120
+ name: `${event.request.method} ${event.route? .id || event.url.pathname }`,
94
121
status: 'ok',
95
122
...traceparentData,
96
123
metadata: {
97
- source: 'route',
124
+ source: event.route?.id ? 'route' : 'url ',
98
125
dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
99
126
},
100
127
},
0 commit comments