Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -885,11 +885,13 @@ import { instrumentLangGraph } from '@sentry/node';
import { instrumentStateGraph } from '@sentry/node';
```

### `childProcess` integration split into `childProcess` and `worker`
### `childProcess` integration split into `childProcess` and `workerThreads`

Affected SDKs: `@sentry/node` and dependents.

The `childProcessIntegration` was split into a `childProcessIntegration` (for `child_process`) and a separate `workerIntegration` (for `worker_threads`).
The `childProcessIntegration` was split into a `childProcessIntegration` (for `child_process`) and a separate `workerThreadsIntegration` (for `worker_threads`).

The deprecated `captureWorkerErrors` option was removed from both integrations. Worker thread errors are always captured now, and disabling `childProcessIntegration` no longer disables worker thread error capture, since that is handled by `workerThreadsIntegration`.

> **TODO(v11):** Document how the two integrations are configured and what users who customized
> `childProcessIntegration` need to change.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Sentry.init({
traceLifecycle: 'static',
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
integrations: [Sentry.childProcessIntegration({ captureWorkerErrors: false })],
integrations: [Sentry.childProcessIntegration(), Sentry.workerThreadsIntegration()],
Comment thread
cursor[bot] marked this conversation as resolved.
transport: loggingTransport,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,22 @@ import { afterAll, expect, test } from 'vitest';
import { conditionalTest } from '../../../utils';
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';

const EVENT = {
// and an exception that is our ANR
const WORKER_ERROR_EVENT = {
exception: {
values: [
{
type: 'Error',
value: 'Worker error',
mechanism: {
type: 'auto.worker_thread',
handled: false,
},
},
],
},
};

const TEST_ERROR_EVENT = {
exception: {
values: [
{
Expand All @@ -23,27 +37,20 @@ const EVENT = {
spawnfile: 'sleep',
},
},
{
timestamp: expect.any(Number),
category: 'worker_thread',
message: "Worker thread errored with 'Worker error'",
level: 'error',
data: {
threadId: expect.any(Number),
},
},
],
};

conditionalTest({ min: 20 })('should capture process and thread breadcrumbs', () => {
conditionalTest({ min: 20 })('should capture child process breadcrumbs and worker thread errors', () => {
afterAll(() => {
cleanupChildProcesses();
});

test('ESM', async () => {
await createRunner(__dirname, 'app.mjs')
.withMockSentryServer()
.expect({ event: EVENT as Event })
.expect({ event: WORKER_ERROR_EVENT as Event })
.expect({ event: TEST_ERROR_EVENT as Event })
Comment thread
cursor[bot] marked this conversation as resolved.
.unordered()
.start()
.completed();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const WORKER_EVENT: Event = {
type: 'Error',
value: 'Test error',
mechanism: {
type: 'auto.child_process.worker_thread',
type: 'auto.worker_thread',
handled: false,
data: {
threadId: expect.any(String),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ describe('OnUncaughtException integration', () => {
type: 'Error',
value: 'job failed',
mechanism: {
type: 'auto.child_process.worker_thread',
type: 'auto.worker_thread',
handled: false,
},
stacktrace: {
Expand Down Expand Up @@ -177,7 +177,7 @@ describe('OnUncaughtException integration', () => {
type: 'Error',
value: 'job failed',
mechanism: {
type: 'auto.child_process.worker_thread',
type: 'auto.worker_thread',
handled: false,
},
stacktrace: {
Expand Down Expand Up @@ -209,7 +209,7 @@ describe('OnUncaughtException integration', () => {
type: 'Error',
value: 'job failed',
mechanism: {
type: 'auto.child_process.worker_thread',
type: 'auto.worker_thread',
handled: false,
},
stacktrace: {
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export {
prismaIntegration,
processSessionIntegration,
childProcessIntegration,
workerThreadsIntegration,
createSentryWinstonTransport,
redisIntegration,
requestDataIntegration,
Expand Down
1 change: 1 addition & 0 deletions packages/aws-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export {
processSessionIntegration,
prismaIntegration,
childProcessIntegration,
workerThreadsIntegration,
createSentryWinstonTransport,
hapiIntegration,
setupHapiErrorHandler,
Expand Down
1 change: 1 addition & 0 deletions packages/google-cloud-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export {
anthropicAIIntegration,
googleGenAIIntegration,
childProcessIntegration,
workerThreadsIntegration,
createSentryWinstonTransport,
vercelAIIntegration,
logger,
Expand Down
1 change: 1 addition & 0 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export {
export * as logger from './logs/exports';

export { childProcessIntegration } from './integrations/childProcess';
export { workerThreadsIntegration } from './integrations/workerThreadsIntegration';
Comment thread
cursor[bot] marked this conversation as resolved.
Comment thread
atharv-sys32 marked this conversation as resolved.
export { consoleIntegration } from './integrations/console';
export { nodeContextIntegration } from './integrations/context';
export { contextLinesIntegration } from './integrations/contextlines';
Expand Down
42 changes: 3 additions & 39 deletions packages/node/src/integrations/childProcess.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ChildProcess } from 'node:child_process';
import * as diagnosticsChannel from 'node:diagnostics_channel';
import type { Worker } from 'node:worker_threads';
import { addBreadcrumb, captureException, defineIntegration, isObjectLike } from '@sentry/core';
import { addBreadcrumb, defineIntegration, isObjectLike } from '@sentry/core';

interface Options {
/**
Expand All @@ -10,19 +9,13 @@ interface Options {
* @default false
*/
includeChildProcessArgs?: boolean;

/**
* Whether to capture errors from worker threads.
*
* @default true
*/
captureWorkerErrors?: boolean;
}

const INTEGRATION_NAME = 'ChildProcess' as const;

/**
* Capture breadcrumbs and events for child processes and worker threads.
* Capture breadcrumbs and events for child processes.
* For worker thread events, use `workerThreadsIntegration()` instead.
*/
export const childProcessIntegration = defineIntegration((options: Options = {}) => {
return {
Expand All @@ -33,12 +26,6 @@ export const childProcessIntegration = defineIntegration((options: Options = {})
captureChildProcessEvents(event.process as ChildProcess, options);
}
});

diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {
if (isObjectLike(event) && 'worker' in event) {
captureWorkerThreadEvents(event.worker as Worker, options);
}
});
},
};
});
Expand Down Expand Up @@ -88,26 +75,3 @@ function captureChildProcessEvents(child: ChildProcess, options: Options): void
}
});
}

function captureWorkerThreadEvents(worker: Worker, options: Options): void {
let threadId: number | undefined;

worker
.on('online', () => {
threadId = worker.threadId;
})
.on('error', error => {
if (options.captureWorkerErrors !== false) {
captureException(error, {
mechanism: { type: 'auto.child_process.worker_thread', handled: false, data: { threadId: String(threadId) } },
});
} else {
addBreadcrumb({
category: 'worker_thread',
message: `Worker thread errored with '${error.message}'`,
level: 'error',
data: { threadId },
});
}
});
}
40 changes: 40 additions & 0 deletions packages/node/src/integrations/workerThreadsIntegration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { Worker } from 'node:worker_threads';
import * as diagnosticsChannel from 'node:diagnostics_channel';
import { captureException, defineIntegration, isObjectLike } from '@sentry/core';

const INTEGRATION_NAME = 'WorkerThreads' as const;

/**
* Capture events and errors of worker threads.
* For child process events, use `childProcessIntegration()` instead.
*/
export const workerThreadsIntegration = defineIntegration(() => {
Comment thread
cursor[bot] marked this conversation as resolved.
return {
name: INTEGRATION_NAME,
setup() {
diagnosticsChannel.channel('worker_threads').subscribe((event: unknown) => {
if (isObjectLike(event) && 'worker' in event) {
captureWorkerThreadEvents(event.worker as Worker);
}
});
},
};
});

function captureWorkerThreadEvents(worker: Worker): void {
let threadId: number | undefined;

worker
.on('online', () => {
threadId = worker.threadId;
})
.on('error', error => {
captureException(error, {
mechanism: {
Comment thread
sentry[bot] marked this conversation as resolved.
type: 'auto.worker_thread',
handled: false,
data: { ...(threadId !== undefined ? { threadId: String(threadId) } : {}) },
},
});
});
}
2 changes: 2 additions & 0 deletions packages/node/src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { detectOrchestrionSetup } from '@sentry/server-utils/orchestrion';
import { registerDiagnosticsChannelInjection } from '@sentry/server-utils/orchestrion/register';
import { DEBUG_BUILD } from '../debug-build';
import { childProcessIntegration } from '../integrations/childProcess';
import { workerThreadsIntegration } from '../integrations/workerThreadsIntegration';
import { consoleIntegration } from '../integrations/console';
import { nodeContextIntegration } from '../integrations/context';
import { contextLinesIntegration } from '../integrations/contextlines';
Expand Down Expand Up @@ -67,6 +68,7 @@ function getBaseDefaultIntegrations(): Integration[] {
localVariablesIntegration(),
nodeContextIntegration(),
childProcessIntegration(),
workerThreadsIntegration(),
processSessionIntegration(),
modulesIntegration(),
];
Expand Down