Skip to content

Commit 1846cef

Browse files
committed
fix(remix): Provide sentry-trace and baggage via root loader.
1 parent 6ea53ed commit 1846cef

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

packages/remix/src/utils/instrumentServer.ts

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/* eslint-disable max-lines */
22
import { captureException, getCurrentHub } from '@sentry/node';
3-
import { getActiveTransaction } from '@sentry/tracing';
3+
import { getActiveTransaction, hasTracingEnabled } from '@sentry/tracing';
44
import {
55
addExceptionMechanism,
66
fill,
7+
isNodeEnv,
78
loadModule,
89
logger,
910
serializeBaggage,
@@ -79,6 +80,8 @@ interface HandleDataRequestFunction {
7980

8081
interface ServerEntryModule {
8182
default: HandleDocumentRequestFunction;
83+
meta: MetaFunction;
84+
loader: DataFunction;
8285
handleDataRequest?: HandleDataRequestFunction;
8386
}
8487

@@ -232,33 +235,30 @@ function makeWrappedLoader(origAction: DataFunction): DataFunction {
232235
return makeWrappedDataFunction(origAction, 'loader');
233236
}
234237

235-
function makeWrappedMeta(origMeta: MetaFunction | HtmlMetaDescriptor = {}): MetaFunction {
236-
return function (
237-
this: unknown,
238-
args: { data: AppData; parentsData: RouteData; params: Params; location: Location },
239-
): HtmlMetaDescriptor {
240-
let origMetaResult;
241-
if (origMeta instanceof Function) {
242-
origMetaResult = origMeta.call(this, args);
243-
} else {
244-
origMetaResult = origMeta;
245-
}
238+
function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
239+
return async function (this: unknown, args: DataFunctionArgs): Promise<Response | AppData> {
240+
let sentryTrace;
241+
let sentryBaggage;
242+
243+
const activeTransaction = getActiveTransaction();
244+
const currentScope = getCurrentHub().getScope();
245+
246+
if (isNodeEnv() && hasTracingEnabled()) {
247+
if (currentScope) {
248+
const span = currentScope.getSpan();
246249

247-
const scope = getCurrentHub().getScope();
248-
if (scope) {
249-
const span = scope.getSpan();
250-
const transaction = getActiveTransaction();
251-
252-
if (span && transaction) {
253-
return {
254-
...origMetaResult,
255-
'sentry-trace': span.toTraceparent(),
256-
baggage: serializeBaggage(transaction.getBaggage()),
257-
};
250+
if (span && activeTransaction) {
251+
sentryTrace = span.toTraceparent();
252+
sentryBaggage = serializeBaggage(activeTransaction.getBaggage());
253+
}
258254
}
259255
}
260256

261-
return origMetaResult;
257+
const res = await origLoader.call(this, args);
258+
259+
Object.assign(res, { sentryTrace, sentryBaggage });
260+
261+
return res;
262262
};
263263
}
264264

@@ -303,12 +303,20 @@ function makeWrappedCreateRequestHandler(
303303
for (const [id, route] of Object.entries(build.routes)) {
304304
const wrappedRoute = { ...route, module: { ...route.module } };
305305

306-
fill(wrappedRoute.module, 'meta', makeWrappedMeta);
307-
308306
if (wrappedRoute.module.action) {
309307
fill(wrappedRoute.module, 'action', makeWrappedAction);
310308
}
311309

310+
// Entry module should have a loader function to provide `sentry-trace` and `baggage`
311+
// They will be available for the root `meta` function as `data.sentryTrace` and `data.sentryBaggage`
312+
if (!wrappedRoute.parentId) {
313+
if (!wrappedRoute.module.loader) {
314+
wrappedRoute.module.loader = () => ({});
315+
}
316+
317+
fill(wrappedRoute.module, 'loader', makeWrappedRootLoader);
318+
}
319+
312320
if (wrappedRoute.module.loader) {
313321
fill(wrappedRoute.module, 'loader', makeWrappedLoader);
314322
}

0 commit comments

Comments
 (0)