Skip to content

Commit b4af1ad

Browse files
chargomeclaude
andcommitted
feat(core): Accept CollectBehavior shorthand for dataCollection.httpHeaders
The docs and the v10.57 changelog advertise `httpHeaders: { deny: [...] }`, but the resolver only understood the `{ request, response }` shape, so a shorthand silently fell through to the defaults. Normalize a boolean or allow/deny object into both directions while keeping `{}` and directional objects on the existing merge path. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 41c40b3 commit b4af1ad

5 files changed

Lines changed: 94 additions & 11 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
Work in this release was contributed by @psh4607, @thijsw, @trinitiwowka, @nehaprasad-dev, @JealousGx, @Jxxunnn, @eddie333016, @davidmurdoch, @yashschandra, @atharv-sys32, @AG0708, @birkskyum, @mkly, @mcbbugu, @suhailopensource, @zkasuran, @mohd-akram, @RealBhupesh, @halillusion, @psang39, and @hafzism. Thank you for your contributions!
88

9+
- feat(core): Accept a `CollectBehavior` shorthand for `dataCollection.httpHeaders`. Passing `true`, `false`, `{ allow: [...] }` or `{ deny: [...] }` now applies to both request and response headers; `{ request, response }` still controls each direction independently.
910
- feat(langchain)!: Emit `gen_ai.pipeline.name` instead of `langchain.chain.name` on LangChain chain spans. The attribute is omitted when the chain is unnamed.
1011
- feat(deno)!: Rename several default integrations to match the other SDKs ([#22404](https://github.com/getsentry/sentry-javascript/pull/22404)). The `deno*Integration` exports are kept as deprecated aliases. If you were relying on the names (for example, to disable them), then note that these have changed:
1112
- `DenoAmqplib` => `Amqplib`

‎packages/core/src/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ export type {
401401
CollectBehavior,
402402
DataCollection,
403403
HttpBodyCollectionTarget,
404+
HttpHeadersCollection,
404405
ResolvedDataCollection,
405406
} from './types/datacollection';
406407
export type { ClientOptions, CoreOptions as Options } from './types/options';

‎packages/core/src/types/datacollection.ts‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ export type CollectBehavior = boolean | { allow: string[] } | { deny: string[] }
1010

1111
export type HttpBodyCollectionTarget = 'incomingRequest' | 'outgoingRequest' | 'incomingResponse' | 'outgoingResponse';
1212

13+
/**
14+
* Controls HTTP header collection per direction.
15+
*/
16+
export interface HttpHeadersCollection {
17+
request?: CollectBehavior;
18+
response?: CollectBehavior;
19+
}
20+
1321
/**
1422
* Controls what data the SDK collects and sends to Sentry.
1523
*
@@ -30,12 +38,11 @@ export interface DataCollection {
3038

3139
/**
3240
* Controls HTTP header collection for requests and responses.
41+
*
42+
* Accepts a `CollectBehavior` applied to both directions, or `{ request, response }` to control each independently.
3343
* @default { request: true, response: true }
3444
*/
35-
httpHeaders?: {
36-
request?: CollectBehavior;
37-
response?: CollectBehavior;
38-
};
45+
httpHeaders?: CollectBehavior | HttpHeadersCollection;
3946

4047
/**
4148
* Which HTTP body types to collect. An omitted value collects all body types valid for the
@@ -118,8 +125,8 @@ export interface DataCollection {
118125
/**
119126
* Fully resolved `DataCollection` with all defaults applied.
120127
*/
121-
export type ResolvedDataCollection = Required<DataCollection> & {
122-
httpHeaders: Required<NonNullable<DataCollection['httpHeaders']>>;
128+
export type ResolvedDataCollection = Required<Omit<DataCollection, 'httpHeaders'>> & {
129+
httpHeaders: Required<HttpHeadersCollection>;
123130
graphQL: Required<NonNullable<DataCollection['graphQL']>>;
124131
genAI: Required<NonNullable<DataCollection['genAI']>>;
125132
};

‎packages/core/src/utils/data-collection/resolveDataCollectionOptions.ts‎

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import type { DataCollection, ResolvedDataCollection } from '../../types/datacollection';
1+
import type {
2+
CollectBehavior,
3+
DataCollection,
4+
HttpHeadersCollection,
5+
ResolvedDataCollection,
6+
} from '../../types/datacollection';
27

38
const DEFAULTS: ResolvedDataCollection = {
49
userInfo: true,
@@ -14,6 +19,25 @@ const DEFAULTS: ResolvedDataCollection = {
1419
frameContextLines: 5,
1520
};
1621

22+
function isCollectBehavior(value: CollectBehavior | HttpHeadersCollection): value is CollectBehavior {
23+
return typeof value === 'boolean' || 'allow' in value || 'deny' in value;
24+
}
25+
26+
function resolveHttpHeaders(httpHeaders: DataCollection['httpHeaders']): ResolvedDataCollection['httpHeaders'] {
27+
if (httpHeaders === undefined) {
28+
return { ...DEFAULTS.httpHeaders };
29+
}
30+
31+
if (isCollectBehavior(httpHeaders)) {
32+
return { request: httpHeaders, response: httpHeaders };
33+
}
34+
35+
return {
36+
request: httpHeaders.request ?? DEFAULTS.httpHeaders.request,
37+
response: httpHeaders.response ?? DEFAULTS.httpHeaders.response,
38+
};
39+
}
40+
1741
/**
1842
* Resolves the effective `DataCollection` configuration from client options.
1943
*
@@ -27,10 +51,7 @@ export function resolveDataCollectionOptions(options: { dataCollection?: DataCol
2751
return {
2852
userInfo: dc.userInfo ?? DEFAULTS.userInfo,
2953
cookies: dc.cookies ?? DEFAULTS.cookies,
30-
httpHeaders: {
31-
request: dc.httpHeaders?.request ?? DEFAULTS.httpHeaders.request,
32-
response: dc.httpHeaders?.response ?? DEFAULTS.httpHeaders.response,
33-
},
54+
httpHeaders: resolveHttpHeaders(dc.httpHeaders),
3455
httpBodies: dc.httpBodies ?? DEFAULTS.httpBodies,
3556
urlQueryParams: dc.urlQueryParams ?? DEFAULTS.urlQueryParams,
3657
graphQL: {

‎packages/core/test/lib/utils/data-collection/resolveDataCollectionOptions.test.ts‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,59 @@ describe('resolveDataCollectionOptions', () => {
6969
expect(result.httpHeaders.response).toBe(true);
7070
});
7171

72+
it('merges nested httpHeaders partially for the response direction', () => {
73+
const result = resolveDataCollectionOptions({
74+
dataCollection: {
75+
httpHeaders: { response: { allow: ['content-type'] } },
76+
},
77+
});
78+
79+
expect(result.httpHeaders).toEqual({ request: true, response: { allow: ['content-type'] } });
80+
});
81+
82+
it('resolves independent request and response header settings', () => {
83+
const result = resolveDataCollectionOptions({
84+
dataCollection: {
85+
httpHeaders: { request: { allow: ['x-request-id'] }, response: false },
86+
},
87+
});
88+
89+
expect(result.httpHeaders).toEqual({ request: { allow: ['x-request-id'] }, response: false });
90+
});
91+
92+
it('treats an empty httpHeaders object as directional config with defaults', () => {
93+
expect(resolveDataCollectionOptions({ dataCollection: { httpHeaders: {} } }).httpHeaders).toEqual({
94+
request: true,
95+
response: true,
96+
});
97+
});
98+
99+
it('applies boolean httpHeaders shorthand to both directions', () => {
100+
expect(resolveDataCollectionOptions({ dataCollection: { httpHeaders: false } }).httpHeaders).toEqual({
101+
request: false,
102+
response: false,
103+
});
104+
105+
expect(resolveDataCollectionOptions({ dataCollection: { httpHeaders: true } }).httpHeaders).toEqual({
106+
request: true,
107+
response: true,
108+
});
109+
});
110+
111+
it('applies allow/deny httpHeaders shorthand to both directions', () => {
112+
const deny = { deny: ['forwarded', '-ip'] };
113+
expect(resolveDataCollectionOptions({ dataCollection: { httpHeaders: deny } }).httpHeaders).toEqual({
114+
request: deny,
115+
response: deny,
116+
});
117+
118+
const allow = { allow: ['content-type'] };
119+
expect(resolveDataCollectionOptions({ dataCollection: { httpHeaders: allow } }).httpHeaders).toEqual({
120+
request: allow,
121+
response: allow,
122+
});
123+
});
124+
72125
it('merges nested genAI partially', () => {
73126
const result = resolveDataCollectionOptions({
74127
dataCollection: {

0 commit comments

Comments
 (0)