process: use exit 1 for uncaughtException
authorisaacs <i@izs.me>
Sat, 7 Sep 2013 00:47:56 +0000 (17:47 -0700)
committerisaacs <i@izs.me>
Sat, 7 Sep 2013 01:23:15 +0000 (18:23 -0700)
Since it is Unix tradition to use exit code 1 for general-purpose script
bail-out, and the way of doing that in Node is to throw an exception and
not catch it, it makes the most sense to exit with 1 when an exception
goes uncaught.

Move the `Invalid Argument` exit to 9, so that it's something specific,
and clear that it's a node internal error.

Also, document the exit codes that we use.

doc/api/process.markdown
src/node.cc
src/node.js
test/simple/test-process-exit-code.js

index 1310a64..df88cfb 100644 (file)
@@ -5,6 +5,50 @@
 The `process` object is a global object and can be accessed from anywhere.
 It is an instance of [EventEmitter][].
 
+## Exit Codes
+
+Node will normally exit with a `0` status code when no more async
+operations are pending.  The following status codes are used in other
+cases:
+
+* `1` **Uncaught Fatal Exception** - There was an uncaught exception,
+  and it was not handled by a domain or an `uncaughtException` event
+  handler.
+* `2` - Unused (reserved by Bash for builtin misuse)
+* `3` **Internal JavaScript Parse Error** - The JavaScript source code
+  internal in Node's bootstrapping process caused a parse error.  This
+  is extremely rare, and generally can only happen during development
+  of Node itself.
+* `4` **Internal JavaScript Evaluation Failure** - The JavaScript
+  source code internal in Node's bootstrapping process failed to
+  return a function value when evaluated.  This is extremely rare, and
+  generally can only happen during development of Node itself.
+* `5` **Fatal Error** - There was a fatal unrecoverable error in V8.
+  Typically a message will be printed to stderr with the prefix `FATAL
+  ERROR`.
+* `6` **Non-function Internal Exception Handler** - There was an
+  uncaught exception, but the internal fatal exception handler
+  function was somehow set to a non-function, and could not be called.
+* `7` **Internal Exception Handler Run-Time Failure** - There was an
+  uncaught exception, and the internal fatal exception handler
+  function itself threw an error while attempting to handle it.  This
+  can happen, for example, if a `process.on('uncaughtException')` or
+  `domain.on('error')` handler throws an error.
+* `8` - Unused.  In previous versions of Node, exit code 8 sometimes
+  indicated an uncaught exception.
+* `9` - **Invalid Argument** - Either an unknown option was specified,
+  or an option requiring a value was provided without a value.
+* `10` **Internal JavaScript Run-Time Failure** - The JavaScript
+  source code internal in Node's bootstrapping process threw an error
+  when the bootstrapping function was called.  This is extremely rare,
+  and generally can only happen during development of Node itself.
+* `12` **Invalid Debug Argument** - The `--debug` and/or `--debug-brk`
+  options were set, but an invalid port number was chosen.
+* `>128` **Signal Exits** - If Node receives a fatal signal such as
+  `SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the
+  value of the signal code.  This is a standard Unix practice, since
+  exit codes are defined to be 7-bit integers, and signal exits set
+  the high-order bit, and then contain the value of the signal code.
 
 ## Event: 'exit'
 
index 0561f9d..b4ce91f 100644 (file)
@@ -1957,7 +1957,7 @@ void FatalException(Handle<Value> error, Handle<Message> message) {
 
   if (false == caught->BooleanValue()) {
     ReportException(error, message);
-    exit(8);
+    exit(1);
   }
 }
 
@@ -2728,7 +2728,7 @@ static void ParseArgs(int* argc,
         eval_string = argv[index + 1];
         if (eval_string == NULL) {
           fprintf(stderr, "%s: %s requires an argument\n", argv[0], arg);
-          exit(1);
+          exit(9);
         }
       } else if (argv[index + 1] != NULL && argv[index + 1][0] != '-') {
         args_consumed += 1;
@@ -3086,7 +3086,7 @@ void Init(int* argc,
   v8_argv = NULL;
 
   if (v8_argc > 1) {
-    exit(1);
+    exit(9);
   }
 
   if (debug_wait_connect) {
index c54bf07..150cfdf 100644 (file)
         try {
           if (!process._exiting) {
             process._exiting = true;
-            process.emit('exit', 8);
+            process.emit('exit', 1);
           }
         } catch (er) {
           // nothing to be done about it at this point.
index e5630f0..6a19db9 100644 (file)
@@ -63,8 +63,8 @@ function child3() {
 function child4() {
   process.exitCode = 99;
   process.on('exit', function(code) {
-    if (code !== 8) {
-      console.log('wrong code! expected 8 for uncaughtException');
+    if (code !== 1) {
+      console.log('wrong code! expected 1 for uncaughtException');
       process.exit(99);
     }
   });
@@ -75,7 +75,7 @@ function parent() {
   test('child1', 42);
   test('child2', 42);
   test('child3', 0);
-  test('child4', 8);
+  test('child4', 1);
 }
 
 function test(arg, exit) {