Skip to content
Merged
1 change: 0 additions & 1 deletion packages/node-core/src/integrations/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ const _nodeContextIntegration = ((options: ContextOptions = {}) => {
async function addContext(event: Event): Promise<Event> {
const updatedContext = _updateContext(await contextsPromise);

// TODO(v11): conditional with `sendDefaultPii` here?
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event.contexts = {
...event.contexts,
app: { ...updatedContext.app, ...event.contexts?.app },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,7 @@ const _httpServerSpansIntegration = ((options: HttpServerSpansIntegrationOptions
'http.flavor': httpVersion,
'net.transport': httpVersion?.toUpperCase() === 'QUIC' ? 'ip_udp' : 'ip_tcp',
...getRequestContentLengthAttribute(request),
...httpHeadersToSpanAttributes(
normalizedRequest.headers || {},
client.getOptions().sendDefaultPii ?? false,
),
...httpHeadersToSpanAttributes(normalizedRequest.headers || {}, client.getDataCollectionOptions()),
},
});

Expand Down
2 changes: 1 addition & 1 deletion packages/node-core/src/integrations/systemError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const systemErrorIntegration = defineIntegration((options: Options = {})
...(error as SystemErrorContext),
};

if (!client.getOptions().sendDefaultPii && options.includePaths !== true) {
if (!client.getDataCollectionOptions().userInfo && options.includePaths !== true) {
delete errorContext.path;
delete errorContext.dest;
}
Expand Down
67 changes: 64 additions & 3 deletions packages/node-core/test/integrations/systemError.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ describe('systemErrorIntegration', () => {
vi.mocked(util.getSystemErrorMap).mockRestore();
});

function createClient(sendDefaultPii = false): Client {
function createClient({ sendDefaultPii, userInfo }: { sendDefaultPii?: boolean; userInfo?: boolean } = {}): Client {
// When userInfo is explicitly provided, use it directly.
// Otherwise fall back to sendDefaultPii (mimicking resolveDataCollectionOptions).
const resolvedUserInfo = userInfo ?? sendDefaultPii ?? false;
Comment thread
chargome marked this conversation as resolved.
return {
getOptions: () => ({ sendDefaultPii }),
getDataCollectionOptions: () => ({ userInfo: resolvedUserInfo }),
} as unknown as Client;
}

Expand Down Expand Up @@ -68,7 +72,7 @@ describe('systemErrorIntegration', () => {
expect(result.exception?.values?.[0]?.value).not.toContain('/secret/path');
});

it('keeps path in context when sendDefaultPii is true', () => {
it('keeps path in context when userInfo is true', () => {
const errno = -2;
vi.mocked(util.getSystemErrorMap).mockReturnValue(
new Map<number, [string, string]>([[errno, ['ENOENT', 'no such file or directory']]]),
Expand All @@ -78,11 +82,68 @@ describe('systemErrorIntegration', () => {
const error = Object.assign(new Error('boom'), { errno, path: '/secret/path' });
const event = { exception: { values: [{ value: error.message }] } } as Event;

const result = integration.processEvent!(event, { originalException: error }, createClient(true)) as Event;
const result = integration.processEvent!(
event,
{ originalException: error },
createClient({ userInfo: true }),
) as Event;

expect(result.contexts?.node_system_error).toEqual({ errno, path: '/secret/path' });
});

it('strips path from context when userInfo is false', () => {
const errno = -2;
vi.mocked(util.getSystemErrorMap).mockReturnValue(
new Map<number, [string, string]>([[errno, ['ENOENT', 'no such file or directory']]]),
);

const integration = systemErrorIntegration();
const error = Object.assign(new Error('boom'), { errno, path: '/secret/path' });
const event = { exception: { values: [{ value: error.message }] } } as Event;

const result = integration.processEvent!(event, { originalException: error }, createClient()) as Event;

expect(result.contexts?.node_system_error).toEqual({ errno });
});

it('keeps path in context when legacy sendDefaultPii is true', () => {
const errno = -2;
vi.mocked(util.getSystemErrorMap).mockReturnValue(
new Map<number, [string, string]>([[errno, ['ENOENT', 'no such file or directory']]]),
);

const integration = systemErrorIntegration();
const error = Object.assign(new Error('boom'), { errno, path: '/secret/path' });
const event = { exception: { values: [{ value: error.message }] } } as Event;

const result = integration.processEvent!(
event,
{ originalException: error },
createClient({ sendDefaultPii: true }),
) as Event;

expect(result.contexts?.node_system_error).toEqual({ errno, path: '/secret/path' });
});

it('strips path from context when legacy sendDefaultPii is false', () => {
const errno = -2;
vi.mocked(util.getSystemErrorMap).mockReturnValue(
new Map<number, [string, string]>([[errno, ['ENOENT', 'no such file or directory']]]),
);

const integration = systemErrorIntegration();
const error = Object.assign(new Error('boom'), { errno, path: '/secret/path' });
const event = { exception: { values: [{ value: error.message }] } } as Event;

const result = integration.processEvent!(
event,
{ originalException: error },
createClient({ sendDefaultPii: false }),
) as Event;

expect(result.contexts?.node_system_error).toEqual({ errno });
});

it('keeps path in context when includePaths option is true', () => {
const errno = -2;
vi.mocked(util.getSystemErrorMap).mockReturnValue(
Expand Down
Loading