Skip to content

Commit ff41cbd

Browse files
committed
properly extract query_params
1 parent d21357d commit ff41cbd

File tree

4 files changed

+32
-20
lines changed

4 files changed

+32
-20
lines changed

packages/astro/src/server/middleware.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import {
1212
startSpan,
1313
withIsolationScope,
1414
} from '@sentry/node';
15-
import type { Scope, SpanAttributes } from '@sentry/types';
15+
import type { Request, Scope, SpanAttributes } from '@sentry/types';
1616
import {
1717
addNonEnumerableProperty,
18+
extractQueryParamsFromUrl,
1819
logger,
1920
objectify,
2021
stripUrlQueryAndFragment,
@@ -111,7 +112,13 @@ async function instrumentRequest(
111112
getCurrentScope().setSDKProcessingMetadata({
112113
// We store the request on the current scope, not isolation scope,
113114
// because we may have multiple requests nested inside each other
114-
normalizedRequest: isDynamicPageRequest ? winterCGRequestToRequestData(request) : { method, url: request.url },
115+
normalizedRequest: (isDynamicPageRequest
116+
? winterCGRequestToRequestData(request)
117+
: {
118+
method,
119+
url: request.url,
120+
query_string: extractQueryParamsFromUrl(request.url),
121+
}) satisfies Request,
115122
});
116123

117124
if (options.trackClientIp && isDynamicPageRequest) {

packages/bun/src/integrations/bunserver.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
withIsolationScope,
1111
} from '@sentry/core';
1212
import type { IntegrationFn, Request, SpanAttributes } from '@sentry/types';
13-
import { getSanitizedUrlString, parseUrl } from '@sentry/utils';
13+
import { extractQueryParamsFromUrl, getSanitizedUrlString, parseUrl } from '@sentry/utils';
1414

1515
const INTEGRATION_NAME = 'BunServer';
1616

@@ -80,6 +80,7 @@ function instrumentBunServeOptions(serveOptions: Parameters<typeof Bun.serve>[0]
8080
url,
8181
method: request.method,
8282
headers: request.headers.toJSON(),
83+
query_string: extractQueryParamsFromUrl(url),
8384
} satisfies Request,
8485
});
8586

packages/node/src/integrations/http/SentryHttpInstrumentation.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getRequestInfo } from '@opentelemetry/instrumentation-http';
88
import { addBreadcrumb, getClient, getIsolationScope, withIsolationScope } from '@sentry/core';
99
import type { PolymorphicRequest, Request, SanitizedRequestData } from '@sentry/types';
1010
import {
11+
extractQueryParamsFromUrl,
1112
getBreadcrumbLogLevelFromHttpStatusCode,
1213
getSanitizedUrlString,
1314
headersToDict,
@@ -146,7 +147,7 @@ export class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpIns
146147
const normalizedRequest: Request = {
147148
url: absoluteUrl,
148149
method: request.method,
149-
query_string: extractQueryParams(request),
150+
query_string: extractQueryParamsFromUrl(request.url || ''),
150151
headers: headersToDict(request.headers),
151152
cookies,
152153
};
@@ -440,19 +441,3 @@ function patchRequestToCaptureBody(req: IncomingMessage, normalizedRequest: Requ
440441
// ignore errors if we can't patch stuff
441442
}
442443
}
443-
444-
function extractQueryParams(req: IncomingMessage): string | undefined {
445-
// req.url is path and query string
446-
if (!req.url) {
447-
return;
448-
}
449-
450-
try {
451-
// The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and
452-
// hostname as the base. Since the point here is just to grab the query string, it doesn't matter what we use.
453-
const queryParams = new URL(req.url, 'http://dogs.are.great').search.slice(1);
454-
return queryParams.length ? queryParams : undefined;
455-
} catch {
456-
return undefined;
457-
}
458-
}

packages/utils/src/requestdata.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,29 @@ export function winterCGRequestToRequestData(req: WebFetchRequest): Request {
462462
return {
463463
method: req.method,
464464
url: req.url,
465+
query_string: extractQueryParamsFromUrl(req.url),
465466
headers,
467+
// TODO: Can we extract body data from the request?
466468
};
467469
}
468470

471+
/** Extract the query params from an URL. */
472+
export function extractQueryParamsFromUrl(url: string): string | undefined {
473+
// url is path and query string
474+
if (!url) {
475+
return;
476+
}
477+
478+
try {
479+
// The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and
480+
// hostname as the base. Since the point here is just to grab the query string, it doesn't matter what we use.
481+
const queryParams = new URL(url, 'http://dogs.are.great').search.slice(1);
482+
return queryParams.length ? queryParams : undefined;
483+
} catch {
484+
return undefined;
485+
}
486+
}
487+
469488
function extractNormalizedRequestData(normalizedRequest: Request, { include }: { include: string[] }): Request {
470489
const includeKeys = include ? (Array.isArray(include) ? include : DEFAULT_REQUEST_INCLUDES) : [];
471490

0 commit comments

Comments
 (0)