Skip to content

Commit 48ef6e1

Browse files
jfmengelssindresorhus
authored andcommitted
Allow no-process-exit to be used in process event handlers (fixes #32) (#44)
1 parent 21612d2 commit 48ef6e1

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

docs/rules/no-process-exit.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Disallow `process.exit()`
22

3-
This rule is an extension to ESLint's [`no-process-exit` rule](http://eslint.org/docs/rules/no-process-exit), that allows `process.exit()` to be called in files that start with a [hashbang](https://en.wikipedia.org/wiki/Shebang_(Unix))`#!/usr/bin/env node`.
3+
This rule is an extension to ESLint's [`no-process-exit` rule](http://eslint.org/docs/rules/no-process-exit), that allows `process.exit()` to be called in files that start with a [hashbang](https://en.wikipedia.org/wiki/Shebang_(Unix))`#!/usr/bin/env node`. It also allows `process.exit()` to be called in `process.on('<event>', func)` event handlers.
44

55

66
## Fail
@@ -16,3 +16,10 @@ process.exit(0);
1616
#!/usr/bin/env node
1717
process.exit(0);
1818
```
19+
20+
```js
21+
process.on('SIGINT', () => {
22+
console.log('Got SIGINT');
23+
process.exit(1);
24+
});
25+
```

rules/no-process-exit.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,29 @@ module.exports = context => {
66
return {};
77
}
88

9+
let processEventHandler = null;
10+
911
return {
10-
CallExpression: node => {
12+
'CallExpression': node => {
1113
const callee = node.callee;
1214

13-
if (callee.type === 'MemberExpression' && callee.object.name === 'process' && callee.property.name === 'exit') {
14-
context.report({
15-
node,
16-
message: 'Only use `process.exit()` in CLI apps. Throw an error instead.'
17-
});
15+
if (callee.type === 'MemberExpression' && callee.object.name === 'process') {
16+
if (callee.property.name === 'on') {
17+
processEventHandler = node;
18+
return;
19+
}
20+
21+
if (callee.property.name === 'exit' && !processEventHandler) {
22+
context.report({
23+
node,
24+
message: 'Only use `process.exit()` in CLI apps. Throw an error instead.'
25+
});
26+
}
27+
}
28+
},
29+
'CallExpression:exit': node => {
30+
if (node === processEventHandler) {
31+
processEventHandler = null;
1832
}
1933
}
2034
};

test/no-process-exit.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,22 @@ const ruleTester = avaRuleTester(test, {
88
}
99
});
1010

11-
const errors = [{ruleId: 'no-process-exit'}];
11+
const errors = [{
12+
ruleId: 'no-process-exit',
13+
message: 'Only use `process.exit()` in CLI apps. Throw an error instead.'
14+
}];
1215

1316
ruleTester.run('no-process-exit', rule, {
1417
valid: [
1518
'#!/usr/bin/env node\n\nprocess.exit();',
1619
'Process.exit()',
1720
'const x = process.exit;',
1821
'x(process.exit)',
22+
'process.on("SIGINT", function() { process.exit(1); })',
23+
'process.on("SIGKILL", function() { process.exit(1); })',
24+
'process.on("SIGINT", () => { process.exit(1); })',
25+
'process.on("SIGINT", () => process.exit(1))',
26+
'process.on("SIGINT", () => { if (true) { process.exit(1); } })',
1927
''
2028
],
2129
invalid: [

0 commit comments

Comments
 (0)