"devDependencies": {
"@types/chai": "^4.1.7",
"@types/chai-as-promised": "^7.1.0",
"@types/mocha": "^5.2.6",
"@types/mock-fs": "^3.6.30",
"@types/node": "^11.11.0",
"@types/sinon": "^7.0.9",
"@typescript-eslint/eslint-plugin": "^1.4.2",
"@typescript-eslint/parser": "^1.4.2",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"eslint": "^5.15.1",
"jest": "^24.4.0",
"mocha": "^6.0.2",
"mock-fs": "^4.8.0",
"sinon": "^7.2.7",
"ts-mockito": "^2.3.1",
"ts-node": "^8.0.3",
"typemoq": "^2.1.0",
"typescript": "^3.3.3333"
},
"dependencies": {
"@types/argparse": "^1.0.36",
"@types/fs-extra": "^5.0.5",
"@types/request-promise": "^4.1.42",
"argparse": "^1.0.10",
"fs-extra": "^7.0.1",
"moment": "^2.24.0",
"queue": "^6.0.0",
"request": "^2.88.0",
"request-promise": "^4.2.4",
"slack": "^11.0.2",
"winston": "^3.2.1"
}
Throwing Error inside the async function is not handled by Winston exception handler, an error is not being logged so information is lost.
const _format = winston.format.printf((info) => `[${moment().format('YYYY/MM/DD hh:mm:ss')}] ${info.level}: ${info.message}`);
winston.createLogger({
transports: [
new winston.transports.File({
filename: path.join(<string>EnvVars.get('ROOT_DIR'), 'logs', 'exceptions.log'), // valid path
format: winston.format.combine(this._format),
handleExceptions: true
})
]
})
(async function(){
throw new Error('test') // not working, exceptions.log is empty
})()
(function(){
throw new Error('test') // works
})()
test.ts
import {createLogger, transports} from 'winston';
createLogger({
transports: [
new transports.File({
filename: 'exception.log',
handleExceptions: true
})
]
});
async function main(): Promise<any>{
throw new Error('test') // not working, exceptions.log is empty
}
function main1(): any{
throw new Error('test') // works
}
main(); // doesn't work
main1(); // works
After compiling to js and running via cmd - only exception in non-promise type function is handled by winston
I guess a workaround would be to use ->
process.on('unhandledRejection', (reason, promise) => {
throw reason;
})
And from there Winston would pick up an exception and log it
We added a RejectionHandler https://github.com/winstonjs/winston/blob/master/lib/winston/rejection-handler.js a few releases back -- I think using that will help with your issue! Might need both exception handler and rejection handler, depending on what kinds of issues you want to catch. Feel free to follow-up if that doesn't solve your issues.
It seems RejectionHandler class doesn't work as expected... I wasn't able to catch rejections with [email protected]
I guess private helper method _addHandler for handler addition was copied from exception handler without any modification.
You use the same flag handleExceptions here instead of handleRejections
/**
* Helper method to add a transport as an exception handler.
* @param {Transport} handler - The transport to add as an exception handler.
* @returns {void}
*/
_addHandler(handler) {
if (!this.handlers.has(handler)) {
handler.handleExceptions = true;
const wrapper = new ExceptionStream(handler);
this.handlers.set(handler, wrapper);
this.logger.pipe(wrapper);
}
}
And after that proivate method _getRejectionHandlers filters assigned transports with handleRejections flag = true
see below:
/**
* Returns the list of transports and exceptionHandlers for this instance.
* @returns {Array} - List of transports and exceptionHandlers for this
* instance.
* @private
*/
_getRejectionHandlers() {
// Remark (indexzero): since `logger.transports` returns all of the pipes
// from the _readableState of the stream we actually get the join of the
// explicit handlers and the implicit transports with
// `handleRejections: true`
return this.logger.transports.filter(wrap => {
const transport = wrap.transport || wrap;
return transport.handleRejections;
});
}
yes, the same issue happen on my project, should be a bug anyway
Most helpful comment
I guess a workaround would be to use ->
And from there Winston would pick up an exception and log it