Skip to content

Commit

Permalink
fix: add uncaughtException handler (#1113)
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 authored Jun 26, 2021
1 parent e85e5f1 commit 8c32165
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
42 changes: 40 additions & 2 deletions packages/bootstrap/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
IMidwayContainer,
} from '@midwayjs/core';
import { join } from 'path';
import { createConsoleLogger, ILogger, IMidwayLogger } from '@midwayjs/logger';
import { createConsoleLogger, ILogger } from '@midwayjs/logger';

export function isTypeScriptEnvironment() {
const TS_MODE_PROCESS_FLAG: string = process.env.MIDWAY_TS_MODE;
Expand Down Expand Up @@ -193,7 +193,7 @@ export class Bootstrap {
if (!this.logger && !configuration.logger) {
this.logger = createConsoleLogger('bootstrapConsole');
if (configuration.logger === false) {
(this.logger as IMidwayLogger)?.disableConsole();
this.logger?.['disableConsole']();
}
configuration.logger = this.logger;
} else {
Expand Down Expand Up @@ -248,6 +248,12 @@ export class Bootstrap {

process.once('exit', this.onExit.bind(this));

this.uncaughtExceptionHandler = this.uncaughtExceptionHandler.bind(this);
process.on('uncaughtException', this.uncaughtExceptionHandler);

this.unhandledRejectionHandler = this.unhandledRejectionHandler.bind(this);
process.on('unhandledRejection', this.unhandledRejectionHandler);

await this.getStarter().init();
return this.getStarter()
.run()
Expand All @@ -262,6 +268,11 @@ export class Bootstrap {

static async stop() {
await this.getStarter().stop();
process.removeListener('uncaughtException', this.uncaughtExceptionHandler);
process.removeListener(
'unhandledRejection',
this.unhandledRejectionHandler
);
this.reset();
}

Expand Down Expand Up @@ -293,4 +304,31 @@ export class Bootstrap {
static onExit(code) {
this.logger.info('[midway:bootstrap] exit with code:%s', code);
}

static uncaughtExceptionHandler(err) {
if (!(err instanceof Error)) {
err = new Error(String(err));
}
if (err.name === 'Error') {
err.name = 'unhandledExceptionError';
}
this.logger.error(err);
}

static unhandledRejectionHandler(err) {
if (!(err instanceof Error)) {
const newError = new Error(String(err));
// err maybe an object, try to copy the name, message and stack to the new error instance
if (err) {
if (err.name) newError.name = err.name;
if (err.message) newError.message = err.message;
if (err.stack) newError.stack = err.stack;
}
err = newError;
}
if (err.name === 'Error') {
err.name = 'unhandledRejectionError';
}
this.logger.error(err);
}
}
21 changes: 21 additions & 0 deletions packages/bootstrap/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ class TestFrameworkUnit implements IMidwayFramework<any, MockConfigurationOption
}
}

const a = null;

class PromiseErrorFramework extends TestFrameworkUnit {
async run(): Promise<any> {
setTimeout(() => {
a();
}, 100);
}
}

describe('/test/index.test.ts', () => {

beforeEach(() => {
Expand Down Expand Up @@ -160,4 +170,15 @@ describe('/test/index.test.ts', () => {
await Bootstrap.stop();
global['MIDWAY_BOOTSTRAP_APP_SET'] = null;
});

it.skip('should catch promise error when start', async () => {
// can't trigger in jest
const framework = new PromiseErrorFramework().configure({
port: 7001,
});
const spy = jest.spyOn(process, 'on');
await Bootstrap.load(framework).run();
await sleep(2000);
expect(spy).toHaveBeenCalled();
});
});

0 comments on commit 8c32165

Please sign in to comment.