Skip to content

Commit e93cf43

Browse files
Merge pull request #13405 from micalevisk/feat/issue-13400
fix(core): auto flush logs on synchronous internal errors
2 parents 2e20dc4 + 47ca9d9 commit e93cf43

File tree

3 files changed

+76
-19
lines changed

3 files changed

+76
-19
lines changed

packages/core/errors/exceptions-zone.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class ExceptionsZone {
99
public static run(
1010
callback: () => void,
1111
teardown: (err: any) => void = DEFAULT_TEARDOWN,
12-
autoFlushLogs?: boolean,
12+
autoFlushLogs: boolean,
1313
) {
1414
try {
1515
callback();
@@ -25,7 +25,7 @@ export class ExceptionsZone {
2525
public static async asyncRun(
2626
callback: () => Promise<void>,
2727
teardown: (err: any) => void = DEFAULT_TEARDOWN,
28-
autoFlushLogs?: boolean,
28+
autoFlushLogs: boolean,
2929
) {
3030
try {
3131
await callback();

packages/core/nest-factory.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,13 @@ export class NestFactoryStatic {
269269

270270
return (...args: unknown[]) => {
271271
let result: unknown;
272-
ExceptionsZone.run(() => {
273-
result = receiver[prop](...args);
274-
}, teardown);
272+
ExceptionsZone.run(
273+
() => {
274+
result = receiver[prop](...args);
275+
},
276+
teardown,
277+
this.autoFlushLogs,
278+
);
275279

276280
return result;
277281
};

packages/core/test/errors/test/exceptions-zone.spec.ts

+67-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { expect } from 'chai';
22
import * as sinon from 'sinon';
3+
import { Logger } from '@nestjs/common';
34
import { ExceptionsZone } from '../../../errors/exceptions-zone';
45

56
describe('ExceptionsZone', () => {
@@ -13,51 +14,103 @@ describe('ExceptionsZone', () => {
1314
callback = sinon.spy();
1415
});
1516
it('should call callback', () => {
16-
ExceptionsZone.run(callback as any, rethrow);
17+
ExceptionsZone.run(callback as any, rethrow, false);
1718
expect(callback.called).to.be.true;
1819
});
1920
describe('when callback throws exception', () => {
2021
const exceptionHandler = {
2122
handle: () => {},
2223
};
2324
let handleSpy: sinon.SinonSpy;
25+
let LoggerFlushSpy: sinon.SinonSpy;
2426
before(() => {
2527
(ExceptionsZone as any).exceptionHandler = exceptionHandler;
2628
handleSpy = sinon.spy(exceptionHandler, 'handle');
29+
LoggerFlushSpy = sinon.spy(Logger, 'flush');
2730
});
28-
it('should call "handle" method of exceptionHandler and rethrows', () => {
29-
const throwsCallback = () => {
30-
throw new Error('');
31-
};
32-
expect(() => ExceptionsZone.run(throwsCallback, rethrow)).to.throws();
33-
expect(handleSpy.called).to.be.true;
31+
after(() => {
32+
LoggerFlushSpy.restore();
33+
});
34+
describe('when callback throws exception and autoFlushLogs is false', () => {
35+
it('should call "handle" method of exceptionHandler and rethrows and not flush logs', () => {
36+
const throwsCallback = () => {
37+
throw new Error('');
38+
};
39+
expect(() =>
40+
ExceptionsZone.run(throwsCallback, rethrow, false),
41+
).to.throws();
42+
43+
expect(handleSpy.called).to.be.true;
44+
45+
expect(LoggerFlushSpy.called).to.be.false;
46+
});
47+
});
48+
49+
describe('when callback throws exception and autoFlushLogs is true', () => {
50+
it('should call "handle" method of exceptionHandler and rethrows and flush logs', () => {
51+
const throwsCallback = () => {
52+
throw new Error('');
53+
};
54+
expect(() =>
55+
ExceptionsZone.run(throwsCallback, rethrow, true),
56+
).to.throws();
57+
58+
expect(handleSpy.called).to.be.true;
59+
60+
expect(LoggerFlushSpy.called).to.be.true;
61+
});
3462
});
3563
});
3664
});
65+
3766
describe('asyncRun', () => {
3867
let callback: sinon.SinonSpy;
3968
beforeEach(() => {
4069
callback = sinon.spy();
4170
});
4271
it('should call callback', async () => {
43-
await ExceptionsZone.asyncRun(callback as any, rethrow);
72+
await ExceptionsZone.asyncRun(callback as any, rethrow, false);
4473
expect(callback.called).to.be.true;
4574
});
4675
describe('when callback throws exception', () => {
4776
const exceptionHandler = {
4877
handle: () => {},
4978
};
5079
let handleSpy: sinon.SinonSpy;
80+
let LoggerFlushSpy: sinon.SinonSpy;
5181
before(() => {
5282
(ExceptionsZone as any).exceptionHandler = exceptionHandler;
5383
handleSpy = sinon.spy(exceptionHandler, 'handle');
84+
LoggerFlushSpy = sinon.spy(Logger, 'flush');
85+
});
86+
after(() => {
87+
LoggerFlushSpy.restore();
5488
});
55-
it('should call "handle" method of exceptionHandler and rethrows error', async () => {
56-
const throwsCallback = () => {
57-
throw new Error('');
58-
};
59-
expect(ExceptionsZone.asyncRun(throwsCallback, rethrow)).to.eventually
60-
.be.rejected;
89+
describe('when callback throws exception and autoFlushLogs is false', () => {
90+
it('should call "handle" method of exceptionHandler and rethrows error and not flush logs', async () => {
91+
const throwsCallback = () => {
92+
throw new Error('');
93+
};
94+
expect(ExceptionsZone.asyncRun(throwsCallback, rethrow, false)).to
95+
.eventually.be.rejected;
96+
97+
expect(handleSpy.called).to.be.true;
98+
99+
expect(LoggerFlushSpy.called).to.be.false;
100+
});
101+
});
102+
describe('when callback throws exception and autoFlushLogs is true', () => {
103+
it('should call "handle" method of exceptionHandler and rethrows error and flush logs', async () => {
104+
const throwsCallback = () => {
105+
throw new Error('');
106+
};
107+
expect(ExceptionsZone.asyncRun(throwsCallback, rethrow, true)).to
108+
.eventually.be.rejected;
109+
110+
expect(handleSpy.called).to.be.true;
111+
112+
expect(LoggerFlushSpy.called).to.be.true;
113+
});
61114
});
62115
});
63116
});

0 commit comments

Comments
 (0)