Skip to content

Commit c5d2c95

Browse files
committed
fix(remix): Provide sentry-trace and baggage via root loader.
1 parent 9b7131f commit c5d2c95

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

packages/remix/src/utils/instrumentServer.ts

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable max-lines */
22
import { captureException, getCurrentHub } from '@sentry/node';
3-
import { getActiveTransaction } from '@sentry/tracing';
4-
import { addExceptionMechanism, fill, loadModule, logger, serializeBaggage } from '@sentry/utils';
3+
import { getActiveTransaction, hasTracingEnabled } from '@sentry/tracing';
4+
import { addExceptionMechanism, fill, isNodeEnv, loadModule, logger, serializeBaggage } from '@sentry/utils';
55

66
// Types vendored from @remix-run/[email protected]:
77
// https://github.com/remix-run/remix/blob/f3691d51027b93caa3fd2cdfe146d7b62a6eb8f2/packages/remix-server-runtime/server.ts
@@ -72,6 +72,8 @@ interface HandleDataRequestFunction {
7272

7373
interface ServerEntryModule {
7474
default: HandleDocumentRequestFunction;
75+
meta: MetaFunction;
76+
loader: DataFunction;
7577
handleDataRequest?: HandleDataRequestFunction;
7678
}
7779

@@ -237,33 +239,30 @@ function makeWrappedLoader(origAction: DataFunction): DataFunction {
237239
return makeWrappedDataFunction(origAction, 'loader');
238240
}
239241

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

252-
const scope = getCurrentHub().getScope();
253-
if (scope) {
254-
const span = scope.getSpan();
255-
const transaction = getActiveTransaction();
256-
257-
if (span && transaction) {
258-
return {
259-
...origMetaResult,
260-
'sentry-trace': span.toTraceparent(),
261-
baggage: serializeBaggage(transaction.getBaggage()),
262-
};
254+
if (span && activeTransaction) {
255+
sentryTrace = span.toTraceparent();
256+
sentryBaggage = serializeBaggage(activeTransaction.getBaggage());
257+
}
263258
}
264259
}
265260

266-
return origMetaResult;
261+
const res = await origLoader.call(this, args);
262+
263+
Object.assign(res, { sentryTrace, sentryBaggage });
264+
265+
return res;
267266
};
268267
}
269268

@@ -378,12 +377,20 @@ function makeWrappedCreateRequestHandler(
378377
for (const [id, route] of Object.entries(build.routes)) {
379378
const wrappedRoute = { ...route, module: { ...route.module } };
380379

381-
fill(wrappedRoute.module, 'meta', makeWrappedMeta);
382-
383380
if (wrappedRoute.module.action) {
384381
fill(wrappedRoute.module, 'action', makeWrappedAction);
385382
}
386383

384+
// Entry module should have a loader function to provide `sentry-trace` and `baggage`
385+
// They will be available for the root `meta` function as `data.sentryTrace` and `data.sentryBaggage`
386+
if (!wrappedRoute.parentId) {
387+
if (!wrappedRoute.module.loader) {
388+
wrappedRoute.module.loader = () => ({});
389+
}
390+
391+
fill(wrappedRoute.module, 'loader', makeWrappedRootLoader);
392+
}
393+
387394
if (wrappedRoute.module.loader) {
388395
fill(wrappedRoute.module, 'loader', makeWrappedLoader);
389396
}

0 commit comments

Comments
 (0)