Unhandled 'error' events kill program
authorRyan Dahl <ry@tinyclouds.org>
Fri, 23 Apr 2010 00:22:03 +0000 (17:22 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Fri, 23 Apr 2010 00:22:06 +0000 (17:22 -0700)
By default 'error' throws. addListener to prevent this.

lib/events.js
lib/http.js
lib/net.js
src/node.js
test/pummel/test-keep-alive.js
test/pummel/test-tcp-timeout.js

index ed00df1..0ac8a69 100644 (file)
@@ -1,5 +1,44 @@
 exports.EventEmitter = process.EventEmitter;
 
+
+process.EventEmitter.prototype.emit = function (type) {
+  if (type == 'error') {
+    if (!this._events || !this._events.error ||
+        (this._events.error instanceof Array && !this._events.error.length)) 
+    {
+      if (arguments[1] instanceof Error) {
+        throw arguments[1];
+      } else {
+        throw new Error("Uncaught, unspecfied 'error' event.");
+      }
+      return false;
+    }
+  }
+
+  if (!this._events) return false;
+  if (!this._events[type]) return false;
+
+  if (typeof this._events[type] == 'function') {
+    var args = Array.prototype.slice.call(arguments, 1);
+
+    this._events[type].apply(this, args);
+    return true;
+
+  } else if (this._events[type] instanceof Array) {
+    var args = Array.prototype.slice.call(arguments, 1);
+
+    
+    var listeners = this._events[type].slice(0);
+    for (var i = 0, l = listeners.length; i < l; i++) {
+      listeners[i].apply(this, args);
+    }
+    return true;
+
+  } else {
+    return false;
+  }
+};
+
 // process.EventEmitter is defined in src/node_events.cc
 // process.EventEmitter.prototype.emit() is also defined there.
 process.EventEmitter.prototype.addListener = function (type, listener) {
@@ -27,6 +66,7 @@ process.EventEmitter.prototype.addListener = function (type, listener) {
   return this;
 };
 
+
 process.EventEmitter.prototype.removeListener = function (type, listener) {
   if ('function' !== typeof listener) {
     throw new Error('removeListener only takes instances of Function');
index ad61baa..884fd9a 100644 (file)
@@ -548,9 +548,13 @@ function connectionListener (socket) {
   parser.socket = socket;
 
   if (self.secure) {
-      socket.setSecure(self.credentials);
+    socket.setSecure(self.credentials);
   }
 
+  socket.addListener('error', function (e) {
+    sys.puts('node http server: ' + e);
+  });
+
   socket.ondata = function (d, start, end) {
     var bytesParsed = parser.execute(d, start, end - start);
     if (parser.incoming && parser.incoming.upgrade) {
index 205b26b..247b596 100644 (file)
@@ -826,20 +826,26 @@ Stream.prototype.destroy = function (exception) {
 
 
 Stream.prototype._shutdown = function () {
-  if (this.writable) {
-    this.writable = false;
+  if (!this.writable) {
+    throw new Error('The connection is not writable');
+  } else {
+    if (this.readable) {
+      // readable and writable
+      this.writable = false;
 
-    if (this.secure) {
-      this._shutdownSecure();
-    }
-    try {
-      shutdown(this.fd, 'write')
-    } catch (e) {
-      this.destroy(e);
-      return;
+      if (this.secure) {
+        this._shutdownSecure();
+      }
+      try {
+        shutdown(this.fd, 'write')
+      } catch (e) {
+        this.destroy(e);
+        return;
+      }
+    } else {
+      // writable but not readable
+      this.destroy();
     }
-
-    if (!this.readable) this.destroy();
   }
 };
 
index 82dd748..253cf0f 100644 (file)
@@ -132,8 +132,6 @@ process.__defineGetter__('stdout', function () {
   var net = module.requireNative('net');
   stdout = new net.Stream(process.binding('stdio').stdoutFD);
 
-  stdout.addListener('error', function (err) { throw err; });
-
   return stdout;
 });
 
@@ -143,7 +141,6 @@ process.openStdin = function () {
   var net = module.requireNative('net');
   var fd = process.binding('stdio').openStdin();
   stdin = new net.Stream(fd);
-  stdin.addListener('error', function (err) { throw err; });
   stdin.resume();
   stdin.readable = true;
   return stdin;
index cc81dfc..18894a8 100644 (file)
@@ -5,9 +5,9 @@ exec = require("child_process").exec;
 
 body = "hello world\n";
 server = http.createServer(function (req, res) {
-  res.writeHead(200, { 
-    "Content-Length": body.length, 
-    "Content-Type": "text/plain"
+  res.writeHead(200, {
+    "Content-Length": body.length,
+    "Content-Type": "text/plain"
   });
   res.write(body);
   res.end();
index 4279daf..1b1fc0c 100644 (file)
@@ -5,6 +5,8 @@ starttime = null;
 timeouttime = null;
 timeout = 1000;
 
+gotError = false
+
 var echo_server = net.createServer(function (socket) {
   socket.setTimeout(timeout);
 
@@ -14,6 +16,11 @@ var echo_server = net.createServer(function (socket) {
     p(timeouttime);
   });
 
+  socket.addListener("error", function (e) {
+    assert.ok(e instanceof Error);
+    gotError = true;
+  })
+
   socket.addListener("data", function (d) {
     puts(d);
     socket.write(d);
@@ -77,4 +84,6 @@ process.addListener("exit", function () {
 
   // Allow for 800 milliseconds more
   assert.ok(diff < timeout + 800);
+
+  assert.ok(gotError);
 });