Я новичок в node.js, хотя я довольно хорошо знаком с JavaScript в целом. Мой вопрос касается "лучших практик" в том, как обрабатывать ошибки в node.js.
Обычно при программировании веб-серверов, серверов FastCGI или веб-страниц на разных языках я использую исключения с блокирующими обработчиками в многопоточной среде. Когда приходит запрос, я обычно делаю что-то вроде этого:
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");
}
Таким образом, я всегда могу обрабатывать внутренние ошибки и отправлять действительный ответ пользователю.
Я понимаю, что с node.js предполагается использовать неблокирующие вызовы, что, очевидно, приводит к разному количеству обратных вызовов, как в этом примере:
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(); // causes exception
response.end(buffer);
}); //fs.read
}); //fs.open
}
Этот пример полностью уничтожит сервер, потому что исключения не вылавливаются. Моя проблема заключается в том, что я больше не могу использовать один try/catch и, таким образом, вообще не поймаю ошибок, которые могут возникнуть при обработке запроса.
Конечно, я мог бы добавить try/catch в каждом обратном вызове, но мне не нравится этот подход, потому что тогда он до программиста, что он не забывает попробовать/поймать. Для сложного сервера с множеством разных и сложных обработчиков это неприемлемо.
Я мог бы использовать глобальный обработчик исключений (предотвращая полный сбой сервера), но затем я не могу отправить ответ пользователю, так как я не знаю, какой запрос приведет к исключению. Это также означает, что запрос остается необработанным/открытым, и браузер ждет навсегда ответа.
Есть ли у кого-то хорошее твердое решение?