• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

winstonjs / winston / 5600816866

pending completion
5600816866

push

github

web-flow
Bug Fix: FileTransportOptions type missing lazy:boolean option (#2334)

* Test for file Transport option rotationFormat

* Test for file Transport option rotationFormat

* Added Lazy option in file transport

* Lint and test

* removed only statement

* Update test/unit/winston/transports/01-file-maxsize.test.js

Co-authored-by: David Hyde <DABH@users.noreply.github.com>

* Update test/unit/winston/transports/01-file-maxsize.test.js

Co-authored-by: David Hyde <DABH@users.noreply.github.com>

* Added lazy in FileTransportOptions types

* Added lazy type in FileTransportInstance

---------

Co-authored-by: myAlapi <myalapi2022@gmail.com>
Co-authored-by: David Hyde <DABH@users.noreply.github.com>

405 of 644 branches covered (62.89%)

Branch coverage included in aggregate %.

725 of 1007 relevant lines covered (72.0%)

1274.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.24
/lib/winston/exception-handler.js
1
/**
2
 * exception-handler.js: Object for handling uncaughtException events.
3
 *
4
 * (C) 2010 Charlie Robbins
5
 * MIT LICENCE
6
 */
7

8
'use strict';
9

10
const os = require('os');
6✔
11
const asyncForEach = require('async/forEach');
6✔
12
const debug = require('@dabh/diagnostics')('winston:exception');
6✔
13
const once = require('one-time');
6✔
14
const stackTrace = require('stack-trace');
6✔
15
const ExceptionStream = require('./exception-stream');
6✔
16

17
/**
18
 * Object for handling uncaughtException events.
19
 * @type {ExceptionHandler}
20
 */
21
module.exports = class ExceptionHandler {
6✔
22
  /**
23
   * TODO: add contructor description
24
   * @param {!Logger} logger - TODO: add param description
25
   */
26
  constructor(logger) {
27
    if (!logger) {
142✔
28
      throw new Error('Logger is required to handle exceptions');
1✔
29
    }
30

31
    this.logger = logger;
141✔
32
    this.handlers = new Map();
141✔
33
  }
34

35
  /**
36
   * Handles `uncaughtException` events for the current process by adding any
37
   * handlers passed in.
38
   * @returns {undefined}
39
   */
40
  handle(...args) {
41
    args.forEach(arg => {
8✔
42
      if (Array.isArray(arg)) {
3!
43
        return arg.forEach(handler => this._addHandler(handler));
4✔
44
      }
45

46
      this._addHandler(arg);
×
47
    });
48

49
    if (!this.catcher) {
8✔
50
      this.catcher = this._uncaughtException.bind(this);
6✔
51
      process.on('uncaughtException', this.catcher);
6✔
52
    }
53
  }
54

55
  /**
56
   * Removes any handlers to `uncaughtException` events for the current
57
   * process. This does not modify the state of the `this.handlers` set.
58
   * @returns {undefined}
59
   */
60
  unhandle() {
61
    if (this.catcher) {
9✔
62
      process.removeListener('uncaughtException', this.catcher);
1✔
63
      this.catcher = false;
1✔
64

65
      Array.from(this.handlers.values())
1✔
66
        .forEach(wrapper => this.logger.unpipe(wrapper));
2✔
67
    }
68
  }
69

70
  /**
71
   * TODO: add method description
72
   * @param {Error} err - Error to get information about.
73
   * @returns {mixed} - TODO: add return description.
74
   */
75
  getAllInfo(err) {
76
    let message = null;
6✔
77
    if (err) {
6✔
78
      message = typeof err === 'string' ? err : err.message;
5✔
79
    }
80

81
    return {
6✔
82
      error: err,
83
      // TODO (indexzero): how do we configure this?
84
      level: 'error',
85
      message: [
86
        `uncaughtException: ${(message || '(no error message)')}`,
7✔
87
        err && err.stack || '  No stack trace'
13✔
88
      ].join('\n'),
89
      stack: err && err.stack,
11✔
90
      exception: true,
91
      date: new Date().toString(),
92
      process: this.getProcessInfo(),
93
      os: this.getOsInfo(),
94
      trace: this.getTrace(err)
95
    };
96
  }
97

98
  /**
99
   * Gets all relevant process information for the currently running process.
100
   * @returns {mixed} - TODO: add return description.
101
   */
102
  getProcessInfo() {
103
    return {
7✔
104
      pid: process.pid,
105
      uid: process.getuid ? process.getuid() : null,
7!
106
      gid: process.getgid ? process.getgid() : null,
7!
107
      cwd: process.cwd(),
108
      execPath: process.execPath,
109
      version: process.version,
110
      argv: process.argv,
111
      memoryUsage: process.memoryUsage()
112
    };
113
  }
114

115
  /**
116
   * Gets all relevant OS information for the currently running process.
117
   * @returns {mixed} - TODO: add return description.
118
   */
119
  getOsInfo() {
120
    return {
7✔
121
      loadavg: os.loadavg(),
122
      uptime: os.uptime()
123
    };
124
  }
125

126
  /**
127
   * Gets a stack trace for the specified error.
128
   * @param {mixed} err - TODO: add param description.
129
   * @returns {mixed} - TODO: add return description.
130
   */
131
  getTrace(err) {
132
    const trace = err ? stackTrace.parse(err) : stackTrace.get();
8✔
133
    return trace.map(site => {
8✔
134
      return {
61✔
135
        column: site.getColumnNumber(),
136
        file: site.getFileName(),
137
        function: site.getFunctionName(),
138
        line: site.getLineNumber(),
139
        method: site.getMethodName(),
140
        native: site.isNative()
141
      };
142
    });
143
  }
144

145
  /**
146
   * Helper method to add a transport as an exception handler.
147
   * @param {Transport} handler - The transport to add as an exception handler.
148
   * @returns {void}
149
   */
150
  _addHandler(handler) {
151
    if (!this.handlers.has(handler)) {
4!
152
      handler.handleExceptions = true;
4✔
153
      const wrapper = new ExceptionStream(handler);
4✔
154
      this.handlers.set(handler, wrapper);
4✔
155
      this.logger.pipe(wrapper);
4✔
156
    }
157
  }
158

159
  /**
160
   * Logs all relevant information around the `err` and exits the current
161
   * process.
162
   * @param {Error} err - Error to handle
163
   * @returns {mixed} - TODO: add return description.
164
   * @private
165
   */
166
  _uncaughtException(err) {
167
    const info = this.getAllInfo(err);
5✔
168
    const handlers = this._getExceptionHandlers();
5✔
169
    // Calculate if we should exit on this error
170
    let doExit = typeof this.logger.exitOnError === 'function'
5✔
171
      ? this.logger.exitOnError(err)
172
      : this.logger.exitOnError;
173
    let timeout;
174

175
    if (!handlers.length && doExit) {
5!
176
      // eslint-disable-next-line no-console
177
      console.warn('winston: exitOnError cannot be true with no exception handlers.');
×
178
      // eslint-disable-next-line no-console
179
      console.warn('winston: not exiting process.');
×
180
      doExit = false;
×
181
    }
182

183
    function gracefulExit() {
184
      debug('doExit', doExit);
3✔
185
      debug('process._exiting', process._exiting);
3✔
186

187
      if (doExit && !process._exiting) {
3!
188
        // Remark: Currently ignoring any exceptions from transports when
189
        // catching uncaught exceptions.
190
        if (timeout) {
3!
191
          clearTimeout(timeout);
3✔
192
        }
193
        // eslint-disable-next-line no-process-exit
194
        process.exit(1);
3✔
195
      }
196
    }
197

198
    if (!handlers || handlers.length === 0) {
5!
199
      return process.nextTick(gracefulExit);
×
200
    }
201

202
    // Log to all transports attempting to listen for when they are completed.
203
    asyncForEach(handlers, (handler, next) => {
5✔
204
      const done = once(next);
5✔
205
      const transport = handler.transport || handler;
5✔
206

207
      // Debug wrapping so that we can inspect what's going on under the covers.
208
      function onDone(event) {
209
        return () => {
10✔
210
          debug(event);
4✔
211
          done();
4✔
212
        };
213
      }
214

215
      transport._ending = true;
5✔
216
      transport.once('finish', onDone('finished'));
5✔
217
      transport.once('error', onDone('error'));
5✔
218
    }, () => doExit && gracefulExit());
4✔
219

220
    this.logger.log(info);
5✔
221

222
    // If exitOnError is true, then only allow the logging of exceptions to
223
    // take up to `3000ms`.
224
    if (doExit) {
5✔
225
      timeout = setTimeout(gracefulExit, 3000);
3✔
226
    }
227
  }
228

229
  /**
230
   * Returns the list of transports and exceptionHandlers for this instance.
231
   * @returns {Array} - List of transports and exceptionHandlers for this
232
   * instance.
233
   * @private
234
   */
235
  _getExceptionHandlers() {
236
    // Remark (indexzero): since `logger.transports` returns all of the pipes
237
    // from the _readableState of the stream we actually get the join of the
238
    // explicit handlers and the implicit transports with
239
    // `handleExceptions: true`
240
    return this.logger.transports.filter(wrap => {
5✔
241
      const transport = wrap.transport || wrap;
5✔
242
      return transport.handleExceptions;
5✔
243
    });
244
  }
245
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc