pmx
Version:
PM2/Keymetrics advanced API
152 lines (117 loc) • 3.72 kB
JavaScript
var debug = require('debug')('axm:notify');
var util = require('util');
var Common = require('./common.js');
var Options = require('./configuration.js');
var Transport = require('./utils/transport.js');
var Notify = {};
var jsonize = function(err, filter, space) {
if (typeof(err) != 'object')
return err;
var plainObject = {};
Object.getOwnPropertyNames(err).forEach(function(key) {
plainObject[key] = err[key];
});
return plainObject;
};
Notify.catchAll = function(opts) {
var callsites = require('./utils/error-callsites')
if (opts === undefined)
opts = { errors : true };
Options.configureModule({
error : opts.errors
});
if (process.env.exec_mode === 'cluster_mode')
return false;
function getUncaughtExceptionListener(listener) {
return function uncaughtListener(err) {
var error = err && err.stack ? err.stack : err;
if (err && err.length) {
err._length = err.length;
delete err.length;
}
if (listener === 'unhandledRejection') {
error = 'You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:\n' + error;
}
console.error(error);
if (err)
var errObj = Notify._interpretError(err);
Transport.send({
type : 'process:exception',
data : errObj !== undefined ? errObj : {message: 'No error but ' + listener + ' was caught!' }
}, true);
if (!process.listeners(listener).filter(function (listener) {
return listener !== uncaughtListener;
}).length) {
if (listener == 'uncaughtException')
process.exit(1);
}
}
}
if (opts.errors === true && util.inspect(process.listeners('uncaughtException')).length === 2) {
process.once('uncaughtException', getUncaughtExceptionListener('uncaughtException'));
process.once('unhandledRejection', getUncaughtExceptionListener('unhandledRejection'));
}
else if (opts.errors === false
&& util.inspect(process.listeners('uncaughtException')).length !== 2) {
process.removeAllListeners('uncaughtException');
process.removeAllListeners('unhandledRejection');
}
};
Notify._interpretError = function(err) {
var s_err = {};
if (typeof(err) === 'string') {
// Simple string processing
s_err.message = err;
s_err.stack = err;
}
else if (!(err instanceof Error) && typeof(err) === 'object') {
// JSON processing
s_err.message = err;
s_err.stack = err;
}
else if (err instanceof Error) {
// Error object type processing
err.stack;
if (err.__error_callsites) {
var stackFrames = [];
err.__error_callsites.forEach(function(callSite) {
stackFrames.push({ file_name: callSite.getFileName(), line_number: callSite.getLineNumber()});
});
err.stackframes = stackFrames;
delete err.__error_callsites;
}
s_err = err;
}
return jsonize(s_err);
};
Notify.notify = function(err) {
var ret_err = this._interpretError(err);
// full_err
//debug(ret_err);
Transport.send({
type : 'process:exception',
data : ret_err
}, true);
return ret_err;
};
Notify.expressErrorHandler = function() {
var self = this;
Options.configureModule({
error : true
});
return function errorHandler(err, req, res, next) {
if (res.statusCode < 400) res.statusCode = 500;
//debug(err.stack || err);
err.url = req.url;
err.component = req.url;
err.action = req.method;
err.params = req.body;
err.session = req.session;
Transport.send({
type : 'process:exception',
data : jsonize(err)
}, true);
return next(err);
};
};
module.exports = Notify;