I'm new to node.js, although I am pretty familiar with JavaScript in general. My question is about "best practices" on how to handle errors in node.js.
Usually when programming web servers, FastCGI servers or web pages in different languages, I use exceptions with blocking handlers in a multi-threaded environment. When the request comes in, I usually do something like this:
function handleRequest(request, response) { try { if (request.url=="whatever") handleWhateverRequest(request, response); else throw new Error("404 not found"); } catch (e) { response.writeHead(500, {'Content-Type': 'text/plain'}); response.end("Server error: "+e.message); } } function handleWhateverRequest(request, response) { if (something) throw new Error("something bad happened"); Response.end("OK"); }
That way, I can always handle internal errors and send a valid response to the user.
I understand that with node.js it is supposed to use non-blocking calls, which obviously leads to a different number of callbacks, as in this example:
var sys = require('sys'), fs = require('fs'); require("http").createServer(handleRequest).listen(8124); function handleRequest(request, response) { fs.open("/proc/cpuinfo", "r", function(error, fd) { if (error) throw new Error("fs.open error: "+error.message); console.log("File open."); var buffer = new require('buffer').Buffer(10); fs.read(fd, buffer, 0, 10, null, function(error, bytesRead, buffer) { buffer.dontTryThisAtHome();
This example will completely destroy the server because exceptions are not caught. My problem is that I can no longer use a single try / catch and thus will not catch any errors that may occur when processing the request.
Of course, I could add try / catch in each callback, but I do not like this approach, because then it is up to the programmer that he does not forget to try / catch. For a complex server with many different and complex handlers, this is unacceptable.
I could use a global exception handler (preventing a server from crashing completely), but then I cannot send a response to the user, since I do not know which request will result in the exception. It also means that the request remains unprocessed / open, and the browser waits forever for a response.
Does anyone have a good solid solution?