• 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

59.66
/lib/winston/rejection-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:rejection');
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 unhandledRejection events.
19
 * @type {RejectionHandler}
20
 */
21
module.exports = class RejectionHandler {
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 rejections');
1✔
29
    }
30

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

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

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

49
    if (!this.catcher) {
1!
50
      this.catcher = this._unhandledRejection.bind(this);
1✔
51
      process.on('unhandledRejection', this.catcher);
1✔
52
    }
53
  }
54

55
  /**
56
   * Removes any handlers to `unhandledRejection` 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) {
8!
62
      process.removeListener('unhandledRejection', this.catcher);
×
63
      this.catcher = false;
×
64

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

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

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

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

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

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

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

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

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

185
    function gracefulExit() {
186
      debug('doExit', doExit);
×
187
      debug('process._exiting', process._exiting);
×
188

189
      if (doExit && !process._exiting) {
×
190
        // Remark: Currently ignoring any rejections from transports when
191
        // catching unhandled rejections.
192
        if (timeout) {
×
193
          clearTimeout(timeout);
×
194
        }
195
        // eslint-disable-next-line no-process-exit
196
        process.exit(1);
×
197
      }
198
    }
199

200
    if (!handlers || handlers.length === 0) {
1!
201
      return process.nextTick(gracefulExit);
×
202
    }
203

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

211
        // Debug wrapping so that we can inspect what's going on under the covers.
212
        function onDone(event) {
213
          return () => {
2✔
214
            debug(event);
×
215
            done();
×
216
          };
217
        }
218

219
        transport._ending = true;
1✔
220
        transport.once('finish', onDone('finished'));
1✔
221
        transport.once('error', onDone('error'));
1✔
222
      },
223
      () => doExit && gracefulExit()
×
224
    );
225

226
    this.logger.log(info);
1✔
227

228
    // If exitOnError is true, then only allow the logging of exceptions to
229
    // take up to `3000ms`.
230
    if (doExit) {
1!
231
      timeout = setTimeout(gracefulExit, 3000);
×
232
    }
233
  }
234

235
  /**
236
   * Returns the list of transports and exceptionHandlers for this instance.
237
   * @returns {Array} - List of transports and exceptionHandlers for this
238
   * instance.
239
   * @private
240
   */
241
  _getRejectionHandlers() {
242
    // Remark (indexzero): since `logger.transports` returns all of the pipes
243
    // from the _readableState of the stream we actually get the join of the
244
    // explicit handlers and the implicit transports with
245
    // `handleRejections: true`
246
    return this.logger.transports.filter(wrap => {
1✔
247
      const transport = wrap.transport || wrap;
1✔
248
      return transport.handleRejections;
1✔
249
    });
250
  }
251
};
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

© 2026 Coveralls, Inc