Skip to content

Commit e16f893

Browse files
committed
Fix excessive framework noise in error stack traces
Add AsyncLocalStorage to LINES_TO_IGNORE (removes OpenTelemetry noise) Apply error stack trace filtering for createJsonErrorObject Add test for framework stack trace filtering Add changeset This change improves readability of error traces in user-facing contexts (Slack alerts, email notifications, API responses, run streams) by filtering out internal framework noise that clutters error messages.
1 parent ed23615 commit e16f893

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

.changeset/dry-taxis-wash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
Improve user-facing error readability by filtering framework noise from stack traces

packages/core/src/v3/errors.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ export function createJsonErrorObject(error: TaskRunError): SerializedError {
227227
return {
228228
name: enhancedError.name,
229229
message: enhancedError.message,
230-
stackTrace: enhancedError.stackTrace,
230+
stackTrace: correctErrorStackTrace(enhancedError.stackTrace, undefined, {
231+
removeFirstLine: false,
232+
}),
231233
};
232234
}
233235
case "STRING_ERROR": {
@@ -400,6 +402,7 @@ const LINES_TO_IGNORE = [
400402
/ZodIpc/,
401403
/startActiveSpan/,
402404
/processTicksAndRejections/,
405+
/AsyncLocalStorage/,
403406
];
404407

405408
function correctStackTraceLine(line: string, projectDir?: string, isDev?: boolean) {

packages/core/test/errors.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { createJsonErrorObject } from "../src/v3/errors.js";
2+
import type { TaskRunError } from "../src/v3/schemas/common.js";
3+
4+
describe("createJsonErrorObject", () => {
5+
it("should filter internal framework noise from error stack traces", () => {
6+
const taskRunError: TaskRunError = {
7+
type: "BUILT_IN_ERROR",
8+
name: "Error",
9+
message: "Network error occurred",
10+
stackTrace: `Error: Network error occurred
11+
at fetchData (file:///src/trigger/utils/helper.ts:4:9)
12+
at processResponse (file:///src/trigger/utils/helper.ts:9:10)
13+
at parseResult (file:///src/trigger/utils/helper.ts:14:10)
14+
at callAPI (file:///src/trigger/services/api.ts:6:10)
15+
at localHelper (file:///src/trigger/example.ts:7:10)
16+
at run (file:///src/trigger/example.ts:17:12)
17+
at _tracer.startActiveSpan.attributes (file:///.npm/_npx/f51a09bd0abf5f10/node_modules/@trigger.dev/core/src/v3/workers/taskExecutor.ts:445:38)
18+
at file:///.npm/_npx/f51a09bd0abf5f10/node_modules/@trigger.dev/core/src/v3/tracer.ts:137:24
19+
at AsyncLocalStorage.run (node:async_hooks:346:14)
20+
at AsyncLocalStorageContextManager.with (file:///.npm/_npx/f51a09bd0abf5f10/node_modules/@opentelemetry/context-async-hooks/src/AsyncLocalStorageContextManager.ts:40:36)`,
21+
};
22+
23+
const jsonError = createJsonErrorObject(taskRunError);
24+
25+
// Should preserve user stack traces
26+
expect(jsonError.stackTrace).toContain(
27+
"at fetchData (file:///src/trigger/utils/helper.ts:4:9)"
28+
);
29+
expect(jsonError.stackTrace).toContain(
30+
"at processResponse (file:///src/trigger/utils/helper.ts:9:10)"
31+
);
32+
expect(jsonError.stackTrace).toContain(
33+
"at parseResult (file:///src/trigger/utils/helper.ts:14:10)"
34+
);
35+
expect(jsonError.stackTrace).toContain("at callAPI (file:///src/trigger/services/api.ts:6:10)");
36+
expect(jsonError.stackTrace).toContain("at localHelper (file:///src/trigger/example.ts:7:10)");
37+
expect(jsonError.stackTrace).toContain("at run (file:///src/trigger/example.ts:17:12)");
38+
39+
// Should filter framework noise
40+
expect(jsonError.stackTrace).not.toContain("_tracer.startActiveSpan.attributes");
41+
expect(jsonError.stackTrace).not.toContain("taskExecutor.ts");
42+
expect(jsonError.stackTrace).not.toContain("tracer.ts");
43+
expect(jsonError.stackTrace).not.toContain("AsyncLocalStorage.run");
44+
expect(jsonError.stackTrace).not.toContain("AsyncLocalStorageContextManager");
45+
expect(jsonError.stackTrace).not.toContain("node_modules/@trigger.dev/core");
46+
expect(jsonError.stackTrace).not.toContain(".npm/_npx");
47+
});
48+
});

0 commit comments

Comments
 (0)