Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/push-server/node_modules/winston/lib/winston/ |
Upload File : |
/** * exception-handler.js: Object for handling uncaughtException events. * * (C) 2010 Charlie Robbins * MIT LICENCE */ 'use strict'; const os = require('os'); const asyncForEach = require('async/forEach'); const debug = require('@dabh/diagnostics')('winston:rejection'); const once = require('one-time'); const stackTrace = require('stack-trace'); const ExceptionStream = require('./exception-stream'); /** * Object for handling unhandledRejection events. * @type {RejectionHandler} */ module.exports = class RejectionHandler { /** * TODO: add contructor description * @param {!Logger} logger - TODO: add param description */ constructor(logger) { if (!logger) { throw new Error('Logger is required to handle rejections'); } this.logger = logger; this.handlers = new Map(); } /** * Handles `unhandledRejection` events for the current process by adding any * handlers passed in. * @returns {undefined} */ handle(...args) { args.forEach(arg => { if (Array.isArray(arg)) { return arg.forEach(handler => this._addHandler(handler)); } this._addHandler(arg); }); if (!this.catcher) { this.catcher = this._unhandledRejection.bind(this); process.on('unhandledRejection', this.catcher); } } /** * Removes any handlers to `unhandledRejection` events for the current * process. This does not modify the state of the `this.handlers` set. * @returns {undefined} */ unhandle() { if (this.catcher) { process.removeListener('unhandledRejection', this.catcher); this.catcher = false; Array.from(this.handlers.values()).forEach(wrapper => this.logger.unpipe(wrapper) ); } } /** * TODO: add method description * @param {Error} err - Error to get information about. * @returns {mixed} - TODO: add return description. */ getAllInfo(err) { let message = null; if (err) { message = typeof err === 'string' ? err : err.message; } return { error: err, // TODO (indexzero): how do we configure this? level: 'error', message: [ `unhandledRejection: ${message || '(no error message)'}`, err && err.stack || ' No stack trace' ].join('\n'), stack: err && err.stack, exception: true, date: new Date().toString(), process: this.getProcessInfo(), os: this.getOsInfo(), trace: this.getTrace(err) }; } /** * Gets all relevant process information for the currently running process. * @returns {mixed} - TODO: add return description. */ getProcessInfo() { return { pid: process.pid, uid: process.getuid ? process.getuid() : null, gid: process.getgid ? process.getgid() : null, cwd: process.cwd(), execPath: process.execPath, version: process.version, argv: process.argv, memoryUsage: process.memoryUsage() }; } /** * Gets all relevant OS information for the currently running process. * @returns {mixed} - TODO: add return description. */ getOsInfo() { return { loadavg: os.loadavg(), uptime: os.uptime() }; } /** * Gets a stack trace for the specified error. * @param {mixed} err - TODO: add param description. * @returns {mixed} - TODO: add return description. */ getTrace(err) { const trace = err ? stackTrace.parse(err) : stackTrace.get(); return trace.map(site => { return { column: site.getColumnNumber(), file: site.getFileName(), function: site.getFunctionName(), line: site.getLineNumber(), method: site.getMethodName(), native: site.isNative() }; }); } /** * 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.handleRejections = true; const wrapper = new ExceptionStream(handler); this.handlers.set(handler, wrapper); this.logger.pipe(wrapper); } } /** * Logs all relevant information around the `err` and exits the current * process. * @param {Error} err - Error to handle * @returns {mixed} - TODO: add return description. * @private */ _unhandledRejection(err) { const info = this.getAllInfo(err); const handlers = this._getRejectionHandlers(); // Calculate if we should exit on this error let doExit = typeof this.logger.exitOnError === 'function' ? this.logger.exitOnError(err) : this.logger.exitOnError; let timeout; if (!handlers.length && doExit) { // eslint-disable-next-line no-console console.warn('winston: exitOnError cannot be true with no rejection handlers.'); // eslint-disable-next-line no-console console.warn('winston: not exiting process.'); doExit = false; } function gracefulExit() { debug('doExit', doExit); debug('process._exiting', process._exiting); if (doExit && !process._exiting) { // Remark: Currently ignoring any rejections from transports when // catching unhandled rejections. if (timeout) { clearTimeout(timeout); } // eslint-disable-next-line no-process-exit process.exit(1); } } if (!handlers || handlers.length === 0) { return process.nextTick(gracefulExit); } // Log to all transports attempting to listen for when they are completed. asyncForEach( handlers, (handler, next) => { const done = once(next); const transport = handler.transport || handler; // Debug wrapping so that we can inspect what's going on under the covers. function onDone(event) { return () => { debug(event); done(); }; } transport._ending = true; transport.once('finish', onDone('finished')); transport.once('error', onDone('error')); }, () => doExit && gracefulExit() ); this.logger.log(info); // If exitOnError is true, then only allow the logging of exceptions to // take up to `3000ms`. if (doExit) { timeout = setTimeout(gracefulExit, 3000); } } /** * 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; }); } };