Skip to content

Commit 0acce2f

Browse files
committed
Add pattern parameter to loader/action args for o11y
1 parent e22a3a1 commit 0acce2f

File tree

8 files changed

+68
-5
lines changed

8 files changed

+68
-5
lines changed

packages/react-router/__tests__/router/fetchers-test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ describe("fetchers", () => {
373373
request: new Request("http://localhost/foo", {
374374
signal: A.loaders.root.stub.mock.calls[0][0].request.signal,
375375
}),
376+
pattern: expect.any(String),
376377
context: {},
377378
});
378379
});
@@ -3373,6 +3374,7 @@ describe("fetchers", () => {
33733374
expect(F.actions.root.stub).toHaveBeenCalledWith({
33743375
params: {},
33753376
request: expect.any(Request),
3377+
pattern: expect.any(String),
33763378
context: {},
33773379
});
33783380

@@ -3402,6 +3404,7 @@ describe("fetchers", () => {
34023404
expect(F.actions.root.stub).toHaveBeenCalledWith({
34033405
params: {},
34043406
request: expect.any(Request),
3407+
pattern: expect.any(String),
34053408
context: {},
34063409
});
34073410

@@ -3429,6 +3432,7 @@ describe("fetchers", () => {
34293432
expect(F.actions.root.stub).toHaveBeenCalledWith({
34303433
params: {},
34313434
request: expect.any(Request),
3435+
pattern: expect.any(String),
34323436
context: {},
34333437
});
34343438

@@ -3456,6 +3460,7 @@ describe("fetchers", () => {
34563460
expect(F.actions.root.stub).toHaveBeenCalledWith({
34573461
params: {},
34583462
request: expect.any(Request),
3463+
pattern: expect.any(String),
34593464
context: {},
34603465
});
34613466

@@ -3484,6 +3489,7 @@ describe("fetchers", () => {
34843489
expect(F.actions.root.stub).toHaveBeenCalledWith({
34853490
params: {},
34863491
request: expect.any(Request),
3492+
pattern: expect.any(String),
34873493
context: {},
34883494
});
34893495

@@ -3514,6 +3520,7 @@ describe("fetchers", () => {
35143520
expect(F.actions.root.stub).toHaveBeenCalledWith({
35153521
params: {},
35163522
request: expect.any(Request),
3523+
pattern: expect.any(String),
35173524
context: {},
35183525
});
35193526

@@ -3543,6 +3550,7 @@ describe("fetchers", () => {
35433550
expect(F.actions.root.stub).toHaveBeenCalledWith({
35443551
params: {},
35453552
request: expect.any(Request),
3553+
pattern: expect.any(String),
35463554
context: {},
35473555
});
35483556

packages/react-router/__tests__/router/router-test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,7 @@ describe("a router", () => {
15031503
request: new Request("http://localhost/tasks", {
15041504
signal: nav.loaders.tasks.stub.mock.calls[0][0].request.signal,
15051505
}),
1506+
pattern: "/tasks",
15061507
context: {},
15071508
});
15081509

@@ -1512,6 +1513,7 @@ describe("a router", () => {
15121513
request: new Request("http://localhost/tasks/1", {
15131514
signal: nav2.loaders.tasksId.stub.mock.calls[0][0].request.signal,
15141515
}),
1516+
pattern: "/tasks/:id",
15151517
context: {},
15161518
});
15171519

@@ -1521,6 +1523,7 @@ describe("a router", () => {
15211523
request: new Request("http://localhost/tasks?foo=bar", {
15221524
signal: nav3.loaders.tasks.stub.mock.calls[0][0].request.signal,
15231525
}),
1526+
pattern: "/tasks",
15241527
context: {},
15251528
});
15261529

@@ -1532,6 +1535,7 @@ describe("a router", () => {
15321535
request: new Request("http://localhost/tasks?foo=bar", {
15331536
signal: nav4.loaders.tasks.stub.mock.calls[0][0].request.signal,
15341537
}),
1538+
pattern: "/tasks",
15351539
context: {},
15361540
});
15371541

@@ -1930,6 +1934,7 @@ describe("a router", () => {
19301934
expect(nav.actions.tasks.stub).toHaveBeenCalledWith({
19311935
params: {},
19321936
request: expect.any(Request),
1937+
pattern: "/tasks",
19331938
context: {},
19341939
});
19351940

@@ -1974,6 +1979,7 @@ describe("a router", () => {
19741979
expect(nav.actions.tasks.stub).toHaveBeenCalledWith({
19751980
params: {},
19761981
request: expect.any(Request),
1982+
pattern: expect.any(String),
19771983
context: {},
19781984
});
19791985
// Assert request internals, cannot do a deep comparison above since some
@@ -2007,6 +2013,7 @@ describe("a router", () => {
20072013
expect(nav.actions.tasks.stub).toHaveBeenCalledWith({
20082014
params: {},
20092015
request: expect.any(Request),
2016+
pattern: expect.any(String),
20102017
context: {},
20112018
});
20122019

packages/react-router/__tests__/router/submission-test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ describe("submissions", () => {
948948
expect(nav.actions.root.stub).toHaveBeenCalledWith({
949949
params: {},
950950
request: expect.any(Request),
951+
pattern: expect.any(String),
951952
context: {},
952953
});
953954

@@ -982,6 +983,7 @@ describe("submissions", () => {
982983
expect(nav.actions.root.stub).toHaveBeenCalledWith({
983984
params: {},
984985
request: expect.any(Request),
986+
pattern: expect.any(String),
985987
context: {},
986988
});
987989

@@ -1014,6 +1016,7 @@ describe("submissions", () => {
10141016
expect(nav.actions.root.stub).toHaveBeenCalledWith({
10151017
params: {},
10161018
request: expect.any(Request),
1019+
pattern: expect.any(String),
10171020
context: {},
10181021
});
10191022

@@ -1118,6 +1121,7 @@ describe("submissions", () => {
11181121
expect(nav.actions.root.stub).toHaveBeenCalledWith({
11191122
params: {},
11201123
request: expect.any(Request),
1124+
pattern: expect.any(String),
11211125
context: {},
11221126
});
11231127

@@ -1156,6 +1160,7 @@ describe("submissions", () => {
11561160
expect(nav.actions.root.stub).toHaveBeenCalledWith({
11571161
params: {},
11581162
request: expect.any(Request),
1163+
pattern: expect.any(String),
11591164
context: {},
11601165
});
11611166

@@ -1191,6 +1196,7 @@ describe("submissions", () => {
11911196
expect(nav.actions.root.stub).toHaveBeenCalledWith({
11921197
params: {},
11931198
request: expect.any(Request),
1199+
pattern: expect.any(String),
11941200
context: {},
11951201
});
11961202

packages/react-router/lib/dom/ssr/routes.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export function createClientRoutes(
340340
(routeModule.clientLoader?.hydrate === true || !route.hasLoader);
341341

342342
dataRoute.loader = async (
343-
{ request, params, context }: LoaderFunctionArgs,
343+
{ request, params, context, pattern }: LoaderFunctionArgs,
344344
singleFetch?: unknown,
345345
) => {
346346
try {
@@ -358,6 +358,7 @@ export function createClientRoutes(
358358
request,
359359
params,
360360
context,
361+
pattern,
361362
async serverLoader() {
362363
preventInvalidServerHandlerCall("loader", route);
363364

@@ -393,7 +394,7 @@ export function createClientRoutes(
393394
);
394395

395396
dataRoute.action = (
396-
{ request, params, context }: ActionFunctionArgs,
397+
{ request, params, context, pattern }: ActionFunctionArgs,
397398
singleFetch?: unknown,
398399
) => {
399400
return prefetchStylesAndCallHandler(async () => {
@@ -412,6 +413,7 @@ export function createClientRoutes(
412413
request,
413414
params,
414415
context,
416+
pattern,
415417
async serverAction() {
416418
preventInvalidServerHandlerCall("action", route);
417419
return fetchServerAction(singleFetch);

packages/react-router/lib/router/router.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
resolveTo,
5858
stripBasename,
5959
RouterContextProvider,
60+
getRoutePattern,
6061
} from "./utils";
6162

6263
////////////////////////////////////////////////////////////////////////////////
@@ -3679,6 +3680,7 @@ export function createStaticHandler(
36793680
let response = await runServerMiddlewarePipeline(
36803681
{
36813682
request,
3683+
pattern: getRoutePattern(matches.map((m) => m.route.path)),
36823684
matches,
36833685
params: matches[0].params,
36843686
// If we're calling middleware then it must be enabled so we can cast
@@ -3910,6 +3912,7 @@ export function createStaticHandler(
39103912
let response = await runServerMiddlewarePipeline(
39113913
{
39123914
request,
3915+
pattern: getRoutePattern(matches.map((m) => m.route.path)),
39133916
matches,
39143917
params: matches[0].params,
39153918
// If we're calling middleware then it must be enabled so we can cast
@@ -4308,6 +4311,7 @@ export function createStaticHandler(
43084311
mapRouteProperties,
43094312
manifest,
43104313
request,
4314+
getRoutePattern(matches.map((m) => m.route.path)),
43114315
match,
43124316
[],
43134317
requestContext,
@@ -4319,6 +4323,7 @@ export function createStaticHandler(
43194323
mapRouteProperties,
43204324
manifest,
43214325
request,
4326+
getRoutePattern(matches.map((m) => m.route.path)),
43224327
match,
43234328
[],
43244329
requestContext,
@@ -4806,6 +4811,7 @@ function getMatchesToLoad(
48064811
mapRouteProperties,
48074812
manifest,
48084813
request,
4814+
getRoutePattern(matches.map((m) => m.route.path)),
48094815
match,
48104816
lazyRoutePropertiesToSkip,
48114817
scopedContext,
@@ -4835,6 +4841,7 @@ function getMatchesToLoad(
48354841
mapRouteProperties,
48364842
manifest,
48374843
request,
4844+
getRoutePattern(matches.map((m) => m.route.path)),
48384845
match,
48394846
lazyRoutePropertiesToSkip,
48404847
scopedContext,
@@ -5602,7 +5609,12 @@ async function runMiddlewarePipeline<Result>(
56025609
) as [string, MiddlewareFunction<Result>][];
56035610

56045611
let result = await callRouteMiddleware(
5605-
{ request, params, context },
5612+
{
5613+
request,
5614+
params,
5615+
context,
5616+
pattern: getRoutePattern(matches.map((m) => m.route.path)),
5617+
},
56065618
tuples,
56075619
handler,
56085620
processResult,
@@ -5724,6 +5736,7 @@ function getDataStrategyMatch(
57245736
mapRouteProperties: MapRoutePropertiesFunction,
57255737
manifest: RouteManifest,
57265738
request: Request,
5739+
pattern: string,
57275740
match: DataRouteMatch,
57285741
lazyRoutePropertiesToSkip: string[],
57295742
scopedContext: unknown,
@@ -5772,6 +5785,7 @@ function getDataStrategyMatch(
57725785
) {
57735786
return callLoaderOrAction({
57745787
request,
5788+
pattern,
57755789
match,
57765790
lazyHandlerPromise: _lazyPromises?.handler,
57775791
lazyRoutePromise: _lazyPromises?.route,
@@ -5818,6 +5832,7 @@ function getTargetedDataStrategyMatches(
58185832
mapRouteProperties,
58195833
manifest,
58205834
request,
5835+
getRoutePattern(matches.map((m) => m.route.path)),
58215836
match,
58225837
lazyRoutePropertiesToSkip,
58235838
scopedContext,
@@ -5845,6 +5860,7 @@ async function callDataStrategyImpl(
58455860
// back out below.
58465861
let dataStrategyArgs = {
58475862
request,
5863+
pattern: getRoutePattern(matches.map((m) => m.route.path)),
58485864
params: matches[0].params,
58495865
context: scopedContext,
58505866
matches,
@@ -5902,13 +5918,15 @@ async function callDataStrategyImpl(
59025918
// Default logic for calling a loader/action is the user has no specified a dataStrategy
59035919
async function callLoaderOrAction({
59045920
request,
5921+
pattern,
59055922
match,
59065923
lazyHandlerPromise,
59075924
lazyRoutePromise,
59085925
handlerOverride,
59095926
scopedContext,
59105927
}: {
59115928
request: Request;
5929+
pattern: string;
59125930
match: AgnosticDataRouteMatch;
59135931
lazyHandlerPromise: Promise<void> | undefined;
59145932
lazyRoutePromise: Promise<void> | undefined;
@@ -5942,6 +5960,7 @@ async function callLoaderOrAction({
59425960
return handler(
59435961
{
59445962
request,
5963+
pattern,
59455964
params: match.params,
59465965
context: scopedContext,
59475966
},

packages/react-router/lib/router/utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ type DefaultContext = MiddlewareEnabled extends true
269269
interface DataFunctionArgs<Context> {
270270
/** A {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Fetch Request instance} which you can use to read headers (like cookies, and {@link https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams URLSearchParams} from the request. */
271271
request: Request;
272+
/**
273+
* Matched un-interpolated route pattern for the current path (i.e., /blog/:slug).
274+
* Mostly useful as a identifier to aggregate on for logging/tracing/etc.
275+
*/
276+
pattern: string;
272277
/**
273278
* {@link https://reactrouter.com/start/framework/routing#dynamic-segments Dynamic route params} for the current route.
274279
* @example
@@ -1995,3 +2000,7 @@ export function isRouteErrorResponse(error: any): error is ErrorResponse {
19952000
"data" in error
19962001
);
19972002
}
2003+
2004+
export function getRoutePattern(paths: (string | undefined)[]) {
2005+
return paths.filter(Boolean).join("/").replace(/\/\/*/g, "/");
2006+
}

packages/react-router/lib/server-runtime/build.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,23 @@ export interface HandleDocumentRequestFunction {
5858
export interface HandleDataRequestFunction {
5959
(
6060
response: Response,
61-
args: LoaderFunctionArgs | ActionFunctionArgs,
61+
args: {
62+
request: LoaderFunctionArgs["request"];
63+
context: LoaderFunctionArgs["context"];
64+
params: LoaderFunctionArgs["params"];
65+
},
6266
): Promise<Response> | Response;
6367
}
6468

6569
export interface HandleErrorFunction {
66-
(error: unknown, args: LoaderFunctionArgs | ActionFunctionArgs): void;
70+
(
71+
error: unknown,
72+
args: {
73+
request: LoaderFunctionArgs["request"];
74+
context: LoaderFunctionArgs["context"];
75+
params: LoaderFunctionArgs["params"];
76+
},
77+
): void;
6778
}
6879

6980
/**

packages/react-router/lib/server-runtime/data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export async function callRouteHandler(
2626
request: stripRoutesParam(stripIndexParam(args.request)),
2727
params: args.params,
2828
context: args.context,
29+
pattern: args.pattern,
2930
});
3031

3132
// If they returned a redirect via data(), re-throw it as a Response

0 commit comments

Comments
 (0)