This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Implement process "uncaughtException" event

This event can be used to overwrite the default exception mechanism which
reports the exception and kills the node process.

See google group post:
http://groups.google.com/group/nodejs/browse_thread/thread/9721dc3a2638446f
  • Loading branch information...
felixge authored and ry committed Nov 14, 2009
1 parent bd6c08a commit 2b252acea47af3ebeac3d7e68277f015667264cc
Showing with 69 additions and 3 deletions.
  1. +44 −2 src/node.cc
  2. +0 −1 src/node.js
  3. +25 −0 test/mjsunit/test-exception-handler.js
View
@@ -524,9 +524,51 @@ static void OnFatalError(const char* location, const char* message) {
exit(1);
}
static int uncaught_exception_counter = 0;
void FatalException(TryCatch &try_catch) {
ReportException(&try_catch);
exit(1);
HandleScope scope;
// Check if uncaught_exception_counter indicates a recursion
if (uncaught_exception_counter > 0) {
ReportException(&try_catch);
exit(1);
}
Local<Value> listeners_v = process->Get(String::NewSymbol("listeners"));
assert(listeners_v->IsFunction());
Local<Function> listeners = Local<Function>::Cast(listeners_v);
Local<String> uncaught_exception = String::NewSymbol("uncaughtException");
Local<Value> argv[1] = { uncaught_exception };
Local<Value> ret = listeners->Call(process, 1, argv);
assert(ret->IsArray());
Local<Array> listener_array = Local<Array>::Cast(ret);
uint32_t length = listener_array->Length();
// Report and exit if process has no "uncaughtException" listener
if (length == 0) {
ReportException(&try_catch);
exit(1);
}
// Otherwise fire the process "uncaughtException" event
Local<Value> emit_v = process->Get(String::NewSymbol("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
Local<Value> error = try_catch.Exception();
Local<Value> event_argv[2] = { uncaught_exception, error };
uncaught_exception_counter++;
emit->Call(process, 2, event_argv);
// Decrement so we know if the next exception is a recursion or not
uncaught_exception_counter--;
}
static ev_async eio_watcher;
View
@@ -677,6 +677,5 @@ if (process.ARGV[1].charAt(0) != "/" && !/^http:\/\//.exec(process.ARGV[1])) {
process.mainModule = createModule(".");
var loadPromise = new process.Promise();
process.mainModule.load(process.ARGV[1], loadPromise);
loadPromise.wait();
}()); // end annonymous namespace
@@ -0,0 +1,25 @@
process.mixin(require("./common"));
var MESSAGE = 'catch me if you can';
var caughtException = false;
process.addListener('uncaughtException', function (e) {
puts("uncaught exception! 1");
assertEquals(MESSAGE, e.message);
caughtException = true;
});
process.addListener('uncaughtException', function (e) {
puts("uncaught exception! 2");
assertEquals(MESSAGE, e.message);
caughtException = true;
});
setTimeout(function() {
throw new Error(MESSAGE);
}, 10);
process.addListener("exit", function () {
puts("exit");
assertTrue(caughtException);
});

0 comments on commit 2b252ac

Please sign in to comment.