Я возвращаю здесь ошибку из обещания Sequelize (Bluebird). Во-первых, это было сделано для изменения сообщения об ошибке, но, как оказалось, это также создает более информативную трассировку стека.Слияние следов стека в восстановленных ошибках
Это что-то вроде
sequelize.sync().catch(originalError => {
const rethrownError = new Error(originalError.msg + ': ' + originalError.sql);
throw rethrownError;
});
Где originalError.stack
не содержит строку, вызвавшую ошибку, но она имеет важную информацию, которая берет свое начало в Sequelize и MySQL драйвера:
SequelizeDatabaseError: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table
at Query.formatError (...\node_modules\sequelize\lib\dialects\mysql\query.js:175:14)
at Query._callback (...\node_modules\sequelize\lib\dialects\mysql\query.js:49:21)
at Query.Sequence.end (...\node_modules\mysql\lib\protocol\sequences\Sequence.js:85:24)
at Query.ErrorPacket (...\node_modules\mysql\lib\protocol\sequences\Query.js:94:8)
at Protocol._parsePacket (...\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (...\node_modules\mysql\lib\protocol\Parser.js:74:12)
at Protocol.write (...\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (...\node_modules\mysql\lib\Connection.js:109:28)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:548:20)
rethrownError.stack
содержит представляющая интерес (первая строка в штабеле), но все остальное - мусор:
Error: ER_KEY_COLUMN_DOES_NOT_EXITS: Key column 'NonExisting' doesn't exist in table
at sequelize.sync.catch (...\app.js:59:17)
at tryCatcher (...\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (...\node_modules\bluebird\js\release\promise.js:504:31)
at Promise._settlePromise (...\node_modules\bluebird\js\release\promise.js:561:18)
at Promise._settlePromise0 (...\node_modules\bluebird\js\release\promise.js:606:10)
at Promise._settlePromises (...\node_modules\bluebird\js\release\promise.js:681:18)
at Async._drainQueue (...\node_modules\bluebird\js\release\async.js:138:16)
at Async._drainQueues (...\node_modules\bluebird\js\release\async.js:148:10)
at Immediate.Async.drainQueues (...\node_modules\bluebird\js\release\async.js:17:14)
at runCallback (timers.js:637:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5)
Я хотел бы сохранить информацию об их обоих - и обозначить связь между ними, а не просто добавить как две несвязанные записи журнала.
Я думал о регистрации их как одной ошибки с конкатенированным стеком, rethrownError.stack += '\n' + originalError.stack
.
Как следует обрабатывать эти две ошибки? Должны ли быть соединены следы стека? Существует ли соглашение о слиянии стеков ошибок в JavaScript (в частности, Node.js)?
Цель состоит в том, чтобы сохранить полученную ошибку значимой и не нарушать существующие инструменты, которые анализируют трассировки стека ошибок (а именно Stacktrace.js).
В рассматриваемых проектах используется логгер Winston или обычный console.error
, поэтому в какой-то момент ошибка стробируется (в приведенном выше примере он был зарегистрирован с помощью обработчика необработанного отклонения).
Как кто-то, кто использовал sequelize справедливый бит: почему вы вообще Повторное выбрасывание?Когда вы нажмете 'catch()', вы должны обрабатывать ошибку таким образом, чтобы не приводить к дальнейшим броскам. –
@ Mike'Pomax'Kamermans Это выходит за рамки вопроса, но я изначально сделал это, чтобы выполнить ошибку 'sql' prop' 'msg', я был не очень рад видеть в журналах ER_KEY_COLUMN_DOES_NOT_EXITS, что не объясняет что-нибудь. Но здесь меня интересует стек из перезапущенной ошибки, 'at sequelize.sync.catch ...'. Исходная ошибка не очевидна вообще там, где она произошла. – estus
Предотвращение спуска [XY Problem] (http://meta.stackexchange.com/a/66378) кроличьей дыры никогда не выходит за рамки. Что касается ошибки из вашего комментария: это невероятно ясная ошибка MySQL, которая говорит вам, что вы используете имя столбца для таблицы, которая не имеет * имя * этого столбца. Ничего не стоит реконструировать ошибки там, вы должны просто зарегистрировать имя таблицы, которую вы пытались использовать, и набор столбцов, которые вы используете, чтобы вы могли проверить против MySQL 'show create table {tablename}' –