Skip to content

Commit 6207f98

Browse files
committed
Improve README
1 parent bb9fb20 commit 6207f98

File tree

2 files changed

+183
-255
lines changed

2 files changed

+183
-255
lines changed

README.md

Lines changed: 183 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ on the console which is very useful. Unfortunately those errors:
2020
[`warning`](https://nodejs.org/api/process.html#process_event_warning) and
2121
[`rejectionHandled`](https://nodejs.org/api/process.html#process_event_rejectionhandled)
2222
making them hard to debug.
23-
- are inconvenient to [log to an external service](docs/API.md#log).
24-
- are hard to [test](docs/API.md#testing).
23+
- are inconvenient to [log to an external service](#log).
24+
- are hard to [test](#testing).
2525
- cannot be conditionally skipped.
2626
- are printed each time an error is repeated (except for
2727
[`warning`](https://nodejs.org/api/process.html#process_event_warning)).
@@ -73,60 +73,220 @@ This package is an ES module and must be loaded using
7373
[an `import` or `import()` statement](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c),
7474
not `require()`.
7575

76-
# Usage
76+
# API
77+
78+
## logProcessErrors(options?)
79+
80+
[`options`](#options) `object?`\
81+
_Return value_: `() => void`
82+
83+
Initializes `log-process-errors`. Should be called as early as possible in the
84+
code, before other `import` statements.
7785

7886
```js
7987
import logProcessErrors from 'log-process-errors'
8088
logProcessErrors(options)
8189
```
8290

83-
`logProcessErrors()` should be called as early as possible in the code, before
84-
other `import` statements.
91+
Returns a function that can be fired to restore Node.js default behavior.
8592

86-
# Options
93+
```js
94+
import logProcessErrors from 'log-process-errors'
8795

88-
`options` is an optional object with the following properties.
96+
const restore = logProcessErrors(options)
97+
restore()
98+
```
99+
100+
## Options
89101

90-
## log
102+
### log
91103

92104
_Type_: `function(error, level, originalError)`
93105

94-
Customizes how process errors are logged.\
95-
[Full documentation](docs/API.md#log).
106+
By default process errors will be logged to the console using `console.error()`,
107+
`console.warn()`, etc.
108+
109+
This behavior can be overridden with the `log` option. For example to log
110+
process errors with [Winston](https://github.com/winstonjs/winston) instead:
111+
112+
```js
113+
import logProcessErrors from 'log-process-errors'
114+
115+
logProcessErrors({
116+
log(error, level, originalError) {
117+
winstonLogger[level](error.stack)
118+
},
119+
})
120+
```
121+
122+
The function's arguments are [`error`](#error), [`level`](#level) and
123+
[`originalError`](#error).
124+
125+
If logging is asynchronous, the function should return a promise (or use
126+
`async`/`await`). This is not necessary if logging is using streams (like
127+
[Winston](https://github.com/winstonjs/winston)).
128+
129+
Duplicate process errors are only logged once (whether the `log` option is
130+
defined or not).
131+
132+
#### error
133+
134+
_Type_: `Error`
96135

97-
## level
136+
The [`log`](#log) and [`level`](#level) options receive as argument an `error`
137+
instance.
138+
139+
This error is generated based on the original process error but with an improved
140+
`name`, `message` and `stack`. However the original process error is still
141+
available as a third argument to [`log`](#log).
142+
143+
##### error.name
144+
145+
_Type_: `string`\
146+
_Value_: [`'UncaughtException'`](https://nodejs.org/api/process.html#process_event_uncaughtexception),
147+
[`'UnhandledRejection'`](https://nodejs.org/api/process.html#process_event_unhandledrejection),
148+
[`'RejectionHandled'`](https://nodejs.org/api/process.html#process_event_rejectionhandled)
149+
or [`'Warning'`](https://nodejs.org/api/process.html#process_event_warning)
150+
151+
##### error.stack
152+
153+
`error` is prettified when using
154+
[`console`](https://nodejs.org/api/console.html#console_console_log_data_args)
155+
or
156+
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options):
157+
158+
```js
159+
console.log(error)
160+
```
161+
162+
![Error prettified](error_pretty.png)
163+
164+
But not when using `error.stack` instead:
165+
166+
```js
167+
console.log(error.stack)
168+
```
169+
170+
![Error raw](error_raw.png)
171+
172+
### level
98173

99174
_Type_: `object`\
100175
_Default_: `{ warning: 'warn', default: 'error' }`
101176

102-
Which log level to use.\
103-
[Full documentation](docs/API.md#level).
177+
Which log level to use.
104178

105-
## exitOn
179+
Object keys are the error names:
180+
[`uncaughtException`](https://nodejs.org/api/process.html#process_event_uncaughtexception),
181+
[`warning`](https://nodejs.org/api/process.html#process_event_warning),
182+
[`unhandledRejection`](https://nodejs.org/api/process.html#process_event_unhandledrejection),
183+
[`rejectionHandled`](https://nodejs.org/api/process.html#process_event_rejectionhandled)
184+
or `default`.
185+
186+
Object values are the log level: `'debug'`, `'info'`, `'warn'`, `'error'`,
187+
`'silent'` or `'default'`. It can also be a function using
188+
[`error` as argument](#error) and returning one of those log levels.
189+
190+
```js
191+
import logProcessErrors from 'log-process-errors'
192+
193+
logProcessErrors({
194+
level: {
195+
// Use `debug` log level for `uncaughtException` instead of `error`
196+
uncaughtException: 'debug',
197+
198+
// Skip some logs based on a condition
199+
default(error) {
200+
return shouldSkip(error) ? 'silent' : 'default'
201+
},
202+
},
203+
})
204+
```
205+
206+
### exitOn
106207

107208
_Type_: `string[]`\
108-
_Default_: `['uncaughtException', 'unhandledRejection']` for Node `>= 15.0.0`, `['uncaughtException']`
109-
otherwise.
209+
_Value_: array of [`'uncaughtException'`](https://nodejs.org/api/process.html#process_event_uncaughtexception),
210+
[`'unhandledRejection'`](https://nodejs.org/api/process.html#process_event_unhandledrejection),
211+
[`'rejectionHandled'`](https://nodejs.org/api/process.html#process_event_rejectionhandled)
212+
or [`'warning'`](https://nodejs.org/api/process.html#process_event_warning)\
213+
_Default_: `['uncaughtException', 'unhandledRejection']` for Node `>= 15.0.0`,
214+
`['uncaughtException']` otherwise.
215+
216+
Which process errors should trigger `process.exit(1)`:
217+
218+
- `['uncaughtException', 'unhandledRejection']` is Node.js default behavior
219+
since Node.js `15.0.0`. Before, only
220+
[`uncaughtException`](https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly)
221+
was enabled.
222+
- use `[]` to prevent any `process.exit(1)`. Recommended if your process is
223+
long-running and does not automatically restart on exit.
110224

111-
Which process errors should trigger `process.exit(1)`.\
112-
[Full documentation](docs/API.md#exiton).
225+
`process.exit(1)` will only be fired after successfully logging the process
226+
error.
113227

114-
## testing
228+
```js
229+
import logProcessErrors from 'log-process-errors'
230+
231+
logProcessErrors({ exitOn: ['uncaughtException', 'unhandledRejection'] })
232+
```
233+
234+
### testing
115235

116236
_Type_: `string`\
117237
_Value_: `'ava'`, `'mocha'`, `'jasmine'`, `'tape'` or `'node_tap'`\
118238
_Default_: `undefined`
119239

120-
When running tests, makes them fail if there are any process errors.\
121-
[Full documentation](docs/API.md#testing).
240+
When running tests, makes them fail if there are any process errors.
241+
242+
Example with [Ava](https://github.com/avajs/ava):
243+
244+
<!-- eslint-disable import/order, import/first -->
245+
246+
```js
247+
import logProcessErrors from 'log-process-errors'
248+
// Should be initialized before requiring other dependencies
249+
logProcessErrors({ testing: 'ava' })
250+
251+
import test from 'ava'
252+
253+
// Tests will fail because a warning is triggered
254+
test('Example test', (t) => {
255+
process.emitWarning('Example warning')
256+
t.pass()
257+
})
258+
```
259+
260+
To ignore specific process errors, use the [`level` option](#level):
261+
262+
<!-- eslint-disable import/order, import/first -->
263+
264+
```js
265+
import logProcessErrors from 'log-process-errors'
266+
// Should be initialized before requiring other dependencies
267+
logProcessErrors({ testing: 'ava', level: { warning: 'silent' } })
268+
269+
import test from 'ava'
270+
271+
// Tests will not fail because warnings are `silent`
272+
test('Example test', (t) => {
273+
process.emitWarning('Example warning')
274+
t.pass()
275+
})
276+
```
122277

123278
## colors
124279

125280
_Type_: `boolean`\
126281
_Default_: `true` if the output is a terminal.
127282

128-
Colorizes messages.\
129-
[Full documentation](docs/API.md#colors).
283+
Colorizes messages.
284+
285+
```js
286+
import logProcessErrors from 'log-process-errors'
287+
288+
logProcessErrors({ colors: false })
289+
```
130290

131291
# Support
132292

0 commit comments

Comments
 (0)