agn-utils/error-handler/error_handler.js

88 lines
2.5 KiB
JavaScript

'use strict';
const util = require('util'),
path = require('path'),
mailer = require('mailer').default,
KeyFileStorage = require("key-file-storage").default,
debug = require('debug')('agm:errHelper');
let logFileName = path.basename(__filename);
/**
* Report important errors to Admin
* @param {*} error Error message in text or the Error object
*/
async function mailErrorToAdmin(error) {
const errorMsg = (error && error.message) ? error.message : error;
const contentOps = {
subject: '[Agm-Errors] Unexpected Errors',
body: error && error.stack ? errorMsg + '\n' + error.stack : errorMsg,
to: process.env.AGM_ADM_EMAIL || '"AgMission Admin" <agm_admin@agnav.com>',
};
return await mailer.sendTextMail(contentOps);
}
async function _handleCriticalError(error, message) {
const exitFunc = (err) => {
debug(err);
process.exit(1);
};
try {
const baseFilename = path.basename(logFileName);
const kfs = KeyFileStorage(path.dirname(logFileName), false);
let lastReport = await kfs[baseFilename];
let curDateTime = new Date();
if (kfs[baseFilename] && (lastReport = kfs[baseFilename])) {
if (lastReport.when && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*$/.test(lastReport.when)) {
if (curDateTime - new Date(lastReport.when) < 2 * 60 * 1e3
&& ((error.code && lastReport.code === error.code) || lastReport.message == error.message))
return exitFunc(error); // Reported the same error two shortly, at least 2 minutes => ignore to avoid flooding with the same emails
}
}
const logObj = {
code: error.code,
message: error.message,
when: curDateTime
};
await kfs(baseFilename, logObj);
} catch (err) {
debug(err);
}
try {
await mailErrorToAdmin(message);
}
catch (err) {
debug(err);
}
finally {
return exitFunc(error);
}
}
/**
* Register the process error handlers
* @param {*} process The process object
* @param {*} fileName The file name to log the error
*/
function registerUnCaughtProcessErrorsHandler(process, fileName) {
if (!process) return;
if (fileName) logFileName = fileName;
process
.on('uncaughtException', async (err) => {
await _handleCriticalError(err, util.format('uncaughtException:', err));
})
.on('unhandledRejection', async (reason, p) => {
await _handleCriticalError(reason, util.format(reason, 'Unhandled Rejection at Promise', p));
});
}
module.exports = {
mailErrorToAdmin, registerUnCaughtProcessErrorsHandler
}