Skip to content

Commit 829b91b

Browse files
fix(observability): pass err via { error } in initErrorRoutes for Winston dedup (#3657)
logger.error(err.stack) passed a string → PostHogErrorTransport couldn't read posthogCaptured → 2 $exception events per uncaught express error. Fixes #3656. Adds unit test for info.error dedup path.
1 parent a91b07b commit 829b91b

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

lib/services/express.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ const initModulesServerRoutes = async (app) => {
265265
const initErrorRoutes = (app) => {
266266
app.use((err, req, res, next) => {
267267
if (!err) return next();
268-
logger.error(err.stack);
268+
logger.error('Unhandled express error', { error: err });
269269
res.status(err.status || 500).send({
270270
message: err.message,
271271
code: err.code,

lib/services/tests/logger.posthog.transport.unit.tests.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ describe('PostHogErrorTransport:', () => {
6868
expect(cb).toHaveBeenCalled();
6969
});
7070

71+
test('skips when info.error.posthogCaptured is true (dedup via { error: err } meta — express initErrorRoutes path)', () => {
72+
const t = new PostHogErrorTransport();
73+
const err = Object.assign(new Error('already captured'), { posthogCaptured: true });
74+
const info = { level: 'error', message: 'Unhandled express error', error: err };
75+
const cb = jest.fn();
76+
t.log(info, cb);
77+
expect(captureExceptionMock).not.toHaveBeenCalled();
78+
expect(cb).toHaveBeenCalled();
79+
});
80+
7181
test('sets posthogCaptured = true on the source Error after forwarding', () => {
7282
const t = new PostHogErrorTransport();
7383
const err = new Error('boom');

0 commit comments

Comments
 (0)