From e02b71ebe876afb66c325a55305e393a8fbcafe5 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 4 Mar 2009 00:31:37 +0100 Subject: [PATCH] exit program on top level exceptions (also lots of reorg.) --- http_api.js | 9 +++++-- node.cc | 74 ++++++++++++++++++++++++++++++--------------------- node.h | 11 ++++++++ node_http.cc | 31 ++++++++------------- node_http.h | 5 +--- node_tcp.cc | 23 +++++++--------- node_tcp.h | 5 +--- node_timer.cc | 23 +++++++--------- node_timer.h | 4 +-- 9 files changed, 95 insertions(+), 90 deletions(-) create mode 100644 node.h diff --git a/http_api.js b/http_api.js index aaeb928be7..703e6aadca 100644 --- a/http_api.js +++ b/http_api.js @@ -3,7 +3,8 @@ function encode(data) { return chunk.length.toString(16) + "\r\n" + chunk + "\r\n"; } -var server = new HTTP.Server("localhost", 8000); +var port = 8000; +var server = new HTTP.Server("localhost", port); server.onRequest = function (request) { @@ -21,8 +22,12 @@ server.onRequest = function (request) { request.respond("Content-Type: text/plain\r\n"); request.respond("Transfer-Encoding: chunked\r\n"); request.respond("\r\n"); - }; + + +log("Running at http://localhost:" + port + "/"); + + /* server.close(); */ diff --git a/node.cc b/node.cc index 402643206b..baf97f6196 100644 --- a/node.cc +++ b/node.cc @@ -1,4 +1,4 @@ -#include +#include "node.h" #include "node_tcp.h" #include "node_http.h" @@ -6,24 +6,37 @@ #include #include + #include #include #include -#include - using namespace v8; using namespace std; -static struct ev_loop *loop; +static int exit_code = 0; -static Persistent context; -static Persistent process_; +void +node_fatal_exception (TryCatch &try_catch) +{ + HandleScope handle_scope; + + Local message = try_catch.Message(); + String::Utf8Value error(try_catch.Exception()); + + fprintf( stderr + , "Uncaught Exception. line %d '%s'\n\n" + , try_catch.Message()->GetLineNumber() + , *error + ); + + ev_unloop(node_loop(), EVUNLOOP_ALL); + exit_code = 1; +} // Reads a file into a v8 string. -static Handle ReadFile - ( const string& name - ) +static Handle +ReadFile (const string& name) { FILE* file = fopen(name.c_str(), "rb"); if (file == NULL) return Handle(); @@ -44,12 +57,8 @@ static Handle ReadFile return result; } -static void ParseOptions - ( int argc - , char* argv[] - , map& options - , string* file - ) +static void +ParseOptions (int argc, char* argv[], map& options, string* file) { for (int i = 1; i < argc; i++) { string arg = argv[i]; @@ -64,9 +73,8 @@ static void ParseOptions } } -static bool compile - ( Handle script - ) +static bool +compile (Handle script) { HandleScope handle_scope; @@ -99,26 +107,30 @@ static bool compile return true; } -static Handle LogCallback - ( const Arguments& args - ) +static Handle +LogCallback (const Arguments& args) { if (args.Length() < 1) return v8::Undefined(); HandleScope scope; Handle arg = args[0]; String::Utf8Value value(arg); - printf("Logged: %s\n", *value); + printf("%s\n", *value); fflush(stdout); return v8::Undefined(); } +static void +OnFatalError (const char* location, const char* message) +{ + fprintf(stderr, "Fatal error. %s %s\n", location, message); + ev_unloop(node_loop(), EVUNLOOP_ALL); +} + int main (int argc, char *argv[]) { - loop = ev_default_loop(0); - map options; string file; ParseOptions(argc, argv, options, &file); @@ -133,24 +145,26 @@ main (int argc, char *argv[]) return 1; } - context = Context::New(NULL, ObjectTemplate::New()); + Persistent context = Context::New(NULL, ObjectTemplate::New()); Context::Scope context_scope(context); Local g = Context::GetCurrent()->Global(); g->Set( String::New("log"), FunctionTemplate::New(LogCallback)->GetFunction()); - g->Set( String::New("TCP"), node_tcp_initialize(loop)); - g->Set( String::New("HTTP"), node_http_initialize(loop)); - node_timer_initialize(g, loop); + node_tcp_initialize(g); + node_http_initialize(g); + node_timer_initialize(g); + + V8::SetFatalErrorHandler(OnFatalError); // Compile and run the script if (!compile(source)) return 1; - ev_loop(loop, 0); + ev_loop(node_loop(), 0); context.Dispose(); - return 0; + return exit_code; } diff --git a/node.h b/node.h new file mode 100644 index 0000000000..4bb9756516 --- /dev/null +++ b/node.h @@ -0,0 +1,11 @@ +#ifndef node_h +#define node_h + +#include +#include + +void node_fatal_exception (v8::TryCatch &try_catch); +#define node_loop() ev_default_loop(0) + +#endif // node_h + diff --git a/node_http.cc b/node_http.cc index a95fb48984..63f0bbf468 100644 --- a/node_http.cc +++ b/node_http.cc @@ -1,4 +1,5 @@ #include "node_http.h" +#include "node.h" #include #include @@ -6,13 +7,10 @@ #include #include -#include - using namespace v8; using namespace std; static Persistent request_template; -static struct ev_loop *loop; // globals static Persistent path_str; @@ -226,10 +224,9 @@ on_headers_complete (ebb_request *req) const int argc = 1; Handle argv[argc] = { js_request }; Handle r = request->connection.js_onRequest->Call(Context::GetCurrent()->Global(), argc, argv); - if (r.IsEmpty()) { - String::Utf8Value error(try_catch.Exception()); - printf("error: %s\n", *error); - } + + if(try_catch.HasCaught()) + node_fatal_exception(try_catch); } static void @@ -346,10 +343,8 @@ HttpRequest::MakeBodyCallback (const char *base, size_t length) Handle result = onBody->Call(js_object, argc, argv); - if (result.IsEmpty()) { - String::Utf8Value error(try_catch.Exception()); - printf("error: %s\n", *error); - } + if(try_catch.HasCaught()) + node_fatal_exception(try_catch); } Local @@ -490,7 +485,7 @@ Server::Start(struct addrinfo *servinfo) { int r = oi_server_listen(&server, servinfo); if(r == 0) - oi_server_attach(&server, loop); + oi_server_attach(&server, node_loop()); return r; } @@ -541,25 +536,23 @@ server_constructor (const Arguments& args) if (r != 0) return Undefined(); // XXX raise error? - printf("Running at http://localhost:%s/\n", *port); - return args.This(); } -Handle -node_http_initialize (struct ev_loop *_loop) +void +node_http_initialize (Handle target) { HandleScope scope; - loop = _loop; - Local http = Object::New(); + target->Set (String::NewSymbol("HTTP"), http); Local server_t = FunctionTemplate::New(server_constructor); server_t->InstanceTemplate()->SetInternalFieldCount(1); http->Set(String::New("Server"), server_t->GetFunction()); + path_str = Persistent::New( String::NewSymbol("path") ); uri_str = Persistent::New( String::NewSymbol("uri") ); query_string_str = Persistent::New( String::NewSymbol("query_string") ); @@ -585,6 +578,4 @@ node_http_initialize (struct ev_loop *_loop) put_str = Persistent::New( String::New("PUT") ); trace_str = Persistent::New( String::New("TRACE") ); unlock_str = Persistent::New( String::New("UNLOCK") ); - - return scope.Close(http); } diff --git a/node_http.h b/node_http.h index 0080bd9b67..71bf8c9ec9 100644 --- a/node_http.h +++ b/node_http.h @@ -2,10 +2,7 @@ #define node_http_h #include -#include -using namespace v8; - -Handle node_http_initialize (struct ev_loop *); +void node_http_initialize (v8::Handle target); #endif diff --git a/node_tcp.cc b/node_tcp.cc index af1860105e..fa4c939d69 100644 --- a/node_tcp.cc +++ b/node_tcp.cc @@ -1,4 +1,5 @@ #include "node_tcp.h" +#include "node.h" #include #include @@ -7,6 +8,7 @@ #include #include +using namespace v8; /* @@ -50,8 +52,6 @@ static struct addrinfo tcp_hints = /* ai_next */ , 0 }; -static struct ev_loop *loop; - class TCPClient { public: oi_task resolve_task; @@ -110,8 +110,7 @@ static void resolve_done client->socket.data = client; oi_socket_connect (&client->socket, client->address); - oi_socket_attach (&client->socket, loop); - + oi_socket_attach (&client->socket, node_loop()); freeaddrinfo(client->address); client->address = NULL; @@ -166,21 +165,17 @@ static Handle Connect oi_async_submit (&thread_pool, &client->resolve_task); } -Handle node_tcp_initialize - ( struct ev_loop *_loop - ) +void +node_tcp_initialize (Handle target) { - loop = _loop; - oi_async_init(&thread_pool); - oi_async_attach(loop, &thread_pool); + oi_async_attach(node_loop(), &thread_pool); HandleScope scope; - Local t = Object::New(); - - t->Set(String::New("connect"), FunctionTemplate::New(Connect)->GetFunction()); + Local tcp = Object::New(); + target->Set(String::NewSymbol("TCP"), tcp); - return scope.Close(t); + tcp->Set(String::NewSymbol("connect"), FunctionTemplate::New(Connect)->GetFunction()); } diff --git a/node_tcp.h b/node_tcp.h index 4bc9fc333b..611e14ca4b 100644 --- a/node_tcp.h +++ b/node_tcp.h @@ -2,10 +2,7 @@ #define node_tcp_h #include -#include -using namespace v8; - -Handle node_tcp_initialize (struct ev_loop *); +void node_tcp_initialize (v8::Handle target); #endif diff --git a/node_timer.cc b/node_timer.cc index d4b4775f84..39e1e27abd 100644 --- a/node_timer.cc +++ b/node_timer.cc @@ -1,7 +1,7 @@ -#include -#include +#include "node.h" +#include "node_timer.h" + using namespace v8; -static struct ev_loop *loop; class Timer { public: @@ -37,12 +37,12 @@ Timer::Timer (Handle _callback, int _argc, Handle _argv[], ev_t ev_timer_init (&watcher, onTimeout, after, repeat); watcher.data = this; - ev_timer_start (loop, &watcher); + ev_timer_start (node_loop(), &watcher); } Timer::~Timer () { - ev_timer_stop (loop, &watcher); + ev_timer_stop (node_loop(), &watcher); callback.Dispose(); @@ -57,11 +57,10 @@ Timer::CallCallback () TryCatch try_catch; - Handle r = callback->Call (Context::GetCurrent()->Global(), argc, argv); - if (r.IsEmpty()) { - String::Utf8Value error(try_catch.Exception()); - printf("timer callback error: %s\n", *error); - } + callback->Call (Context::GetCurrent()->Global(), argc, argv); + + if(try_catch.HasCaught()) + node_fatal_exception(try_catch); } Local @@ -166,10 +165,8 @@ static Handle setInterval } void -node_timer_initialize (Handle target, struct ev_loop *_loop) +node_timer_initialize (Handle target) { - loop = _loop; - HandleScope scope; target->Set ( String::New("setTimeout") diff --git a/node_timer.h b/node_timer.h index 7c73bdd6b7..5e4dacd38b 100644 --- a/node_timer.h +++ b/node_timer.h @@ -1,10 +1,8 @@ #ifndef node_timer_h #define node_timer_h -#include #include -using namespace v8; -void node_timer_initialize (Handle target, struct ev_loop *_loop); +void node_timer_initialize (v8::Handle target); #endif // node_timer_h