Необнаруживаемые ошибки в node.js

Итак, я пытаюсь написать простой сервер сокетов TCP, который передает информацию всем подключенным клиентам. Поэтому, когда пользователь подключается, они добавляются в список клиентов, а когда поток испускает событие закрытия, они удаляются из списка клиентов.

Это хорошо работает, за исключением того, что иногда я отправляю сообщение так же, как пользователь отключается.

Я попытался обернуть stream.write() в блок try/catch, но не повезло. Похоже, что ошибка неуловима.

Ответ 1

Решение состоит в том, чтобы добавить слушателя для события "ошибка" потока. Сначала это может показаться интуитивно понятным, но оправдание для него звучит.

stream.write() отправляет данные асинхронно. К тому моменту, когда node понял, что запись в сокет вызвала ошибку, ваш код переместился дальше, после вызова stream.write, так что нет способа поднять там ошибку.

Вместо этого, что node делает в этой ситуации, выдает событие "ошибка" из потока, а EventEmitter кодируется таким образом, что, если нет прослушивателей для события "ошибка" , ошибка возникает как исключение из верхнего уровня, и процесс завершается.

Ответ 2

Питер прав,

и есть и другой способ, вы также можете сделать catch для всех обработчиков ошибок с помощью

process.on('uncaughtException',function(error){
// process error
})

это поймает все, что брошено...

обычно лучше делать это, как только это возможно, однако, если вы, где написано, скажем, тестовая среда, может быть хорошей идеей использовать process.on('uncaughtException',...

вот суть, которая охватывает (я думаю) все разные способы обработки ошибок в nodejs http://gist.github.com/636290

Ответ 3

У меня была такая же проблема с примером сервера времени из здесь Мои клиенты убиваются, а сервер времени пытается записать в закрытый сокет.

Установка обработчика ошибок не работает, поскольку событие ошибки запускается только при приеме. Сервер времени не принимает, (см. Документацию о событиях потока).

Мое решение - установить обработчик в событии закрытия потока.

stream.on('close', function() {
    subscribers.remove(stream);
    stream.end();
    console.log('Subscriber CLOSE: ' + subscribers.length + " total.\n");
});