Как отлаживать ошибки node.js, когда мой код не встречается в трассировке стека? - программирование

Как отлаживать ошибки node.js, когда мой код не встречается в трассировке стека?

И на самом деле, я не совсем понимаю, почему мой код не находится в трассировке стека, если node является однопоточным. Может быть, я принципиально недопонимаю, что-то, но почему мое приложение иногда умирает со стеком, у которого нет ничего, что я написал в нем?

Я пишу довольно простой прокси-сервер, используя node/express. В качестве примера я периодически получал эту "ошибку зависания сокета":

Error: socket hang up
 at createHangUpError (_http_client.js:250:15)
 at Socket.socketOnEnd (_http_client.js:342:23)
 at emitNone (events.js:91:20)
 at Socket.emit (events.js:185:7)
 at endReadableNT (_stream_readable.js:926:12)
 at _combinedTickCallback (internal/process/next_tick.js:74:11)
 at process._tickCallback (internal/process/next_tick.js:98:9) code: 'ECONNRESET' }

И поскольку ни один из файлов javascript в трассировке стека не является моим, я понятия не имел, откуда это взялось. Это было в основном проб и ошибок, пытаясь поймать ошибки и добавить обработчики ошибок в стиле .on, пока я не нашел нужное место.

Мне кажется, что я принципиально пропущу что-то - что я должен делать по-другому, чтобы отлаживать такие ошибки? Как я могу узнать, где его обрабатывать, если я не вижу, что (в моем коде) вызывает его? Как узнать, должен ли я использовать блок try/catch или что-то вроде request.on('error') {...}?

4b9b3361

Ответ 1

Некоторые ошибки, такие как упомянутые вами, не вызваны вашим кодом. Фактически это вызвано отсутствием кода в вашей заявке. (Например, ваш код приложения, вероятно, не содержит кода для изящного обращения с ECONNRESET, то есть удаленного разъединения разъемов.

Теперь на ваш вопрос о том, как отлаживать такие ошибки (включая сторонний код). Конечно, вы можете использовать трассировку стека и longjohn и т.д.

Но для меня проще и быстрее решить запустить приложение в режиме отладки с опцией - проверить с помощью Отладчик Chrome, чтобы проверить его (нет точек останова), с включенной опцией Пауза на исключениях. Это все, что вам нужно. Теперь, когда есть исключение, хром-отладчик приостанавливает приложение точно в строке, где генерируется исключение. Делает это намного легче, чтобы найти такие ошибки.

Пауза при исключении

Надеюсь, это поможет вам!

Ответ 2

Вы можете сделать что-то вроде отладки таких ошибок.

process.on('uncaughtException', function(err) {
  console.log(err.stack);
  throw err;
});

Вы также можете увеличить размер размера трассировки стека и/или размер стека.

node --stack_trace_limit=200 app.js //defaults to 10
node --stack-size=1024 app.js // defaults to 492kB

Ответ 3

В отличие от вашего предположения, парадигма единственного потока node.js вызывает эти типы ошибок. В многопоточной среде, такой как java, все вызываемые функции выполняются внутри функции вызывающего абонента:

java -> A -> B -> C -> D

Итак, если A() завернут в попытку и поймают все внутренние исключения, будут пойманы.

Но в среде Async функция обратного вызова выполняется вне функции вызывающего абонента:

node -> A -> B(C)
node -> I -> C -> D

Здесь функция A вызывает асинхронную функцию B (обычно библиотеку) с функцией обратного вызова C в качестве аргумента, функция B запускает задачу async после завершения функции node.js вызова I, которая является внутренней функцией этой библиотеки и он вызывает функцию C. Здесь вы видите I, C и D вне вашего кода.

Итак, здесь есть две вещи:

1- вы должны обернуть код функции обратного вызова в try и catch.

2- может быть исключение в функции I, которое вы не можете поймать в своем коде. Вот те исключения, о которых вы говорите, ни один из файлов javascript в трассировке стека не является вашим, потому что он не инициируется в вашем коде.

Теперь, если функция B (ее библиотека) написана хорошо, она должна предоставить некоторые средства для захвата этих исключений. Один из них будет on('error', cb). Поэтому вы всегда должны проверять библиотечную документацию, чтобы узнать, как вы можете поймать и обработать такие исключения.

Если библиотека плохо написана и ничего не предусмотрено, чтобы уловить ее исключения в вашем коде, вы можете использовать отладчик, например, chrome inspector или отладчик WebStorm, чтобы поймать их, но нет другого способа, кроме как управлять его исходным кодом, так что, по крайней мере, они обходят ваш код, или вы можете подать отчет об ошибке.

Node.js также предоставляют обработчик исключенных исключений, который захватывает все неперехваченные исключения:

process.on('uncaughtException', (err) => {
    process.exit(1);
});

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

Ответ 4

Stack Trace не содержит ваш файл, потому что этот тип ошибки возникает при проблемах с сервером, например:

Время ожидания хоста

[ 'code' ]
e.code => ECONNRESET

Консольный выход

{ Error: socket hang up
    at createHangUpError (_http_client.js:250:15)
    at TLSSocket.socketCloseListener (_http_client.js:282:23)
    at emitOne (events.js:101:20)
    at TLSSocket.emit (events.js:188:7)
    at TCP._handle.close [as _onclose] (net.js:492:12) code: 'ECONNRESET' }

ИЛИ когда сервер неожиданно завершает соединение или не отправляет ответ.

Подробнее... node коды ошибок приложения.

или обратитесь к этому issue.

Ответ 5

Вы можете попробовать встроенный отладчик для node.js. Этот отладчик позволяет вам выполнить код, который не является вашим.

node debug script.js

Другим хорошим инструментом является node-inspector.

В этой статье приведены некоторые другие параметры отладки, которые могут быть полезны при определении причины вашего исключения: Как отлаживать приложения node.js?