Skip to content

Commit 7c63039

Browse files
committed
Add more features
1 parent 8768199 commit 7c63039

File tree

10 files changed

+192
-116
lines changed

10 files changed

+192
-116
lines changed

README.md

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,46 +19,60 @@ const onProcessError = require('on-process-error')
1919
const undoSetup = onProcessError.setup()
2020
```
2121

22-
When any process errors occur, it will be logged using `console.error()`:
22+
When any process errors occur, it will be logged using `console.error()`.
23+
The message will include detailed information about the error.
2324

24-
- the message will include detailed information about the error
25-
- for `warning`, `console.warn()` will be used instead.
26-
- for `uncaughtException`, [`process.exit(1)` will be called after
27-
`console.error()`](https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly).
25+
For `warning`, `console.warn()` will be used instead.
2826

2927
You can undo everything by firing the function returned by
3028
`onProcessError.setup()` (called `undoSetup` in the example above).
3129

30+
# Example output
31+
32+
TO BE DONE
33+
3234
# Custom handling
3335

34-
You can override the default behavior by passing a custom function instead.
36+
You can override the default behavior by passing a custom function to the
37+
`handle` option.
3538

3639
<!-- eslint-disable no-empty-function, no-unused-vars, node/no-missing-require,
37-
import/no-unresolved, unicorn/filename-case, strict -->
40+
import/no-unresolved, unicorn/filename-case, strict, no-undef -->
3841

3942
```js
40-
const onProcessError = require('on-process-error')
41-
42-
const undoSetup = onProcessError.setup(
43-
({ eventName, promiseState, promiseValue, error, message }) => {},
44-
)
43+
onProcessError.setup({
44+
handle({ eventName, promiseState, promiseValue, error, message }) {},
45+
})
4546
```
4647

48+
This can be useful if you want to use your own logger instead of the console.
49+
4750
The function's argument is an object with the following properties:
4851

4952
- `eventName` `{string}`: can be `uncaughtException`, `unhandledRejection`,
5053
`rejectionHandled`, `multipleResolves` or `warning`
54+
- `error` `{any}` is either:
55+
- value thrown by `uncaughtException`. Usually an `Error` instance, but not
56+
always.
57+
- `Error` instance emitted by `warning`.
58+
[`error.name`, `error.code` and `error.detail`](https://nodejs.org/api/process.html#process_event_warning)
59+
might be defined.
5160
- `promiseState` `{string}`: whether promise was `resolved` or `rejected`.
5261
For `unhandledRejection`, `rejectionHandled` and `multipleResolves`.
5362
- `promiseValue` `{any}`: value resolved/rejected by the promise.
5463
For `unhandledRejection`, `rejectionHandled` and `multipleResolves`.
55-
- `error` `{error}`:
56-
- can be:
57-
- thrown by `uncaughtException`
58-
- emitted by `warning`. [`error.name`, `error.code` and `error.detail`](https://nodejs.org/api/process.html#process_event_warning)
59-
might be defined.
60-
- rejected by `unhandledRejection`, `rejectionHandled` or
61-
`multipleResolves`'s promise (if the promise was rejected).
62-
- if the error is not an `Error` instance (e.g. if it is a string), it will
63-
be normalized to one using `new Error()`.
6464
- `message` `{string}`: detailed message summing up all of the above.
65+
66+
# Exiting on uncaught exceptions
67+
68+
By default, `uncaughtException` will fire `process.exit(1)`. This is the recommended behavior according to the
69+
[Node.js documentation](https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly).
70+
71+
You can disable this by setting the `exitOnExceptions` option to `false`:
72+
73+
<!-- eslint-disable no-empty-function, no-unused-vars, node/no-missing-require,
74+
import/no-unresolved, unicorn/filename-case, strict, no-undef -->
75+
76+
```js
77+
onProcessError.setup({ exitOnExceptions: false })
78+
```

package-lock.json

Lines changed: 3 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
},
3737
"author": "autoserver founder <[email protected]> (http://autoserver.io)",
3838
"directories": {},
39-
"dependencies": {},
39+
"dependencies": {
40+
"chalk": "^2.4.1"
41+
},
4042
"devDependencies": {
4143
"eslint": "^5.7.0",
4244
"eslint-config-prettier": "^3.1.0",

src/default.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
'use strict'
22

3-
const { exit } = require('process')
4-
53
// Default event handler
64
const defaultHandler = function({ eventName, message }) {
75
const level = eventName === 'warning' ? 'warn' : 'error'
86
// eslint-disable-next-line no-restricted-globals, no-console
97
console[level](message)
10-
11-
// See https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly
12-
if (eventName === 'uncaughtException') {
13-
exit(1)
14-
}
158
}
169

1710
module.exports = {

src/error.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/events.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const warning = function(context, error) {
1414
}
1515

1616
const unhandledRejection = function(context, promiseValue, promise) {
17-
handleEvent({ ...context, promise })
17+
handleEvent({ ...context, promise, promiseValue })
1818
}
1919

2020
const rejectionHandled = function(context, promise) {

src/handle.js

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,50 @@
11
'use strict'
22

3-
const { getError } = require('./error')
3+
const { exit } = require('process')
4+
5+
const { parsePromise } = require('./promise')
46
const { getMessage } = require('./message')
57

68
// Generic event handler for all events.
7-
const handleEvent = async function({ handlerFunc, eventName, error, promise }) {
8-
const { promiseState, promiseValue } = await parsePromise({ promise })
9-
const errorA = getError({ error, promiseValue })
9+
const handleEvent = async function({
10+
opts: { handlerFunc, exitOnExceptions },
11+
eventName,
12+
error,
13+
promise,
14+
promiseValue,
15+
}) {
16+
const { promiseState, promiseValue: promiseValueA } = await parsePromise({
17+
eventName,
18+
promise,
19+
promiseValue,
20+
})
1021
const message = getMessage({
1122
eventName,
1223
promiseState,
13-
promiseValue,
14-
error: errorA,
24+
promiseValue: promiseValueA,
25+
error,
1526
})
1627

17-
handlerFunc({ eventName, promiseState, promiseValue, error: errorA, message })
28+
handlerFunc({
29+
eventName,
30+
promiseState,
31+
promiseValue: promiseValueA,
32+
error,
33+
message,
34+
})
35+
36+
exitProcess({ eventName, exitOnExceptions })
1837
}
1938

20-
// Retrieve promise's resolved/rejected state and value.
21-
const parsePromise = async function({ promise }) {
22-
// `uncaughtException` and `warning` events do not have `promise`.
23-
if (promise === undefined) {
24-
return {}
39+
// Exit process on `uncaughtException`
40+
// See https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly
41+
// Can be disabled with `opts.exitOnExceptions: false`
42+
const exitProcess = function({ eventName, exitOnExceptions }) {
43+
if (eventName !== 'uncaughtException' || !exitOnExceptions) {
44+
return
2545
}
2646

27-
try {
28-
const promiseValue = await promise
29-
return { promiseState: 'resolved', promiseValue }
30-
} catch (error) {
31-
return { promiseState: 'rejected', promiseValue: error }
32-
}
47+
exit(1)
3348
}
3449

3550
module.exports = {

src/main.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,27 @@ const { defaultHandler } = require('./default')
66
const EVENTS = require('./events')
77

88
// Add event handling for all process-related errors
9-
const setup = function(handlerFunc = defaultHandler) {
10-
const listeners = addListeners({ handlerFunc })
9+
const setup = function(opts) {
10+
const optsA = { ...DEFAULT_OPTS, ...opts }
11+
12+
const listeners = addListeners({ opts: optsA })
1113
const removeAll = removeListeners.bind(null, listeners)
1214
return removeAll
1315
}
1416

15-
const addListeners = function({ handlerFunc }) {
16-
return Object.entries(EVENTS).map((eventName, eventFunc) =>
17-
addListener({ handlerFunc, eventName, eventFunc }),
17+
const DEFAULT_OPTS = {
18+
handlerFunc: defaultHandler,
19+
exitOnExceptions: true,
20+
}
21+
22+
const addListeners = function({ opts }) {
23+
return Object.entries(EVENTS).map(([eventName, eventFunc]) =>
24+
addListener({ opts, eventName, eventFunc }),
1825
)
1926
}
2027

21-
const addListener = function({ handlerFunc, eventName, eventFunc }) {
22-
const eventListener = eventFunc.bind(null, { handlerFunc, eventName })
28+
const addListener = function({ opts, eventName, eventFunc }) {
29+
const eventListener = eventFunc.bind(null, { opts, eventName })
2330
process.on(eventName, eventListener)
2431

2532
return { eventListener, eventName }

0 commit comments

Comments
 (0)