fix(server): avoid global rejection when event handler errors (#10467)

This commit is contained in:
liuyi
2025-02-27 14:25:46 +08:00
committed by GitHub
parent caa4dfedfc
commit b3821ad619
5 changed files with 103 additions and 24 deletions

View File

@@ -4,7 +4,7 @@ import { CLS_ID, ClsServiceManager } from 'nestjs-cls';
import Sinon from 'sinon';
import { EventBus, metrics } from '../../base';
import { createTestingModule } from '../utils';
import { createTestingModule, sleep } from '../utils';
import { Listeners } from './provider';
export const test = ava as TestFn<{
@@ -201,3 +201,55 @@ test('should continuously use the same request id', async t => {
t.true(listeners.onRequestId.lastCall.returned('test-request-id'));
});
test('should throw when emitting async event with uncaught error', async t => {
const { eventbus } = t.context;
await t.throwsAsync(
() => eventbus.emitAsync('__test__.throw', { count: 0 }),
{
message: 'Error in event handler',
}
);
});
test('should suppress thrown error when emitting async event', async t => {
const { eventbus } = t.context;
const spy = Sinon.spy();
// @ts-expect-error internal event
const off = eventbus.on('error', spy);
const promise = eventbus.emitAsync('__test__.suppressThrow', {});
await t.notThrowsAsync(promise);
t.true(spy.calledOnce);
const args = spy.firstCall.args[0];
t.is(args.event, '__test__.suppressThrow');
t.deepEqual(args.payload, {});
t.is(args.error.message, 'Error in event handler');
const returns = await promise;
t.deepEqual(returns, [undefined]);
off();
});
test('should catch thrown error when emitting sync event', async t => {
const { eventbus } = t.context;
const spy = Sinon.spy();
// @ts-expect-error internal event
const off = eventbus.on('error', spy);
t.notThrows(() => eventbus.emit('__test__.throw', { count: 0 }));
// wait a tick
await sleep(1);
t.true(spy.calledOnce);
const args = spy.firstCall.args[0];
t.is(args.event, '__test__.throw');
t.deepEqual(args.payload, { count: 0 });
t.is(args.error.message, 'Error in event handler');
off();
});

View File

@@ -8,6 +8,7 @@ declare global {
'__test__.event': { count: number };
'__test__.event2': { count: number };
'__test__.throw': { count: number };
'__test__.suppressThrow': {};
'__test__.requestId': {};
}
}
@@ -32,6 +33,11 @@ export class Listeners {
throw new Error('Error in event handler');
}
@OnEvent('__test__.suppressThrow', { suppressError: true })
onSuppressThrow() {
throw new Error('Error in event handler');
}
@OnEvent('__test__.requestId')
onRequestId() {
const cls = ClsServiceManager.getClsService();