在Bookshelf的保存挂钩中抛出错误时,我遇到了未处理拒绝错误的问题。 Bookshelf有一个custom event handler,可以使用事件的Promises,以及一个extended version of Bluebird的Promises。
'use strict'
const knex = require('./src/knex')
const Bookshelf = require('bookshelf')
const bookshelf = Bookshelf(knex)
class MyModel extends bookshelf.Model {
get tableName () {
return 'my_table'
}
initialize () {
bookshelf.Model.prototype.initialize.call(this)
this.on('saving', () => {
throw new Error('Some validation')
})
}
}
async function main () {
try {
await bookshelf.transaction(async (trx) => {
return MyModel
.forge({
id: 0,
})
.save(null, {
patch: true,
transacting: trx,
})
})
} catch (err) {
console.log(err)
}
}
main()
这是输出:
knex:tx trx1: Starting top level transaction +0ms
Unhandled rejection Error: Some validation
at MyModel.on (/test.js:18:13)
at /node_modules/bookshelf/lib/base/events.js:176:25
From previous event:
at MyModel.triggerThen (/node_modules/bookshelf/lib/base/events.js:175:32)
at MyModel.<anonymous> (/node_modules/bookshelf/lib/model.js:1045:19)
From previous event:
at MyModel.<anonymous> (/node_modules/bookshelf/lib/model.js:970:8)
From previous event:
at bookshelf.transaction (/test.js:30:10)
at /node_modules/knex/lib/transaction.js:81:20
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)
From previous event:
at /node_modules/knex/lib/transaction.js:75:10
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
From previous event:
at new Transaction (/node_modules/knex/lib/transaction.js:68:41)
at Client_PG.transaction (/node_modules/knex/lib/client.js:158:12)
at Object.transaction (/node_modules/knex/lib/util/make-knex.js:75:21)
at Object.transaction (/node_modules/bookshelf/lib/bookshelf.js:247:36)
at main (/test.js:25:21)
at Object.<anonymous> (/test.js:40:1)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
knex:tx trx1: releasing connection +55ms
Error: Some validation
at MyModel.on (/test.js:18:13)
at /node_modules/bookshelf/lib/base/events.js:176:25
From previous event:
at MyModel.triggerThen (/node_modules/bookshelf/lib/base/events.js:175:32)
at MyModel.<anonymous> (/node_modules/bookshelf/lib/model.js:1045:19)
From previous event:
at MyModel.<anonymous> (/node_modules/bookshelf/lib/model.js:970:8)
From previous event:
at bookshelf.transaction (/test.js:30:10)
at /node_modules/knex/lib/transaction.js:81:20
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)
From previous event:
at /node_modules/knex/lib/transaction.js:75:10
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
From previous event:
at new Transaction (/node_modules/knex/lib/transaction.js:68:41)
at Client_PG.transaction (/node_modules/knex/lib/client.js:158:12)
at Object.transaction (/node_modules/knex/lib/util/make-knex.js:75:21)
at Object.transaction (/node_modules/bookshelf/lib/bookshelf.js:247:36)
at main (/test.js:25:21)
at Object.<anonymous> (/test.js:40:1)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
当我从async
移除await bookshelf.transaction(async (trx) => {
时,错误消失。我知道这里的异步是不必要的,但我很好奇为什么这会导致拒绝被处理?
修改1
我没有在没有Bookshelf的情况下复制错误。
async function main () {
try {
await test1()
} catch (err) {
console.log(err)
}
}
async function test1 () {
return Promise.resolve().then(() => {
throw new Error('Some validation')
})
}
main()
这不会产生未处理的拒绝。
修改2
async function main () {
try {
await test2()
} catch (err) {
console.log(err)
}
}
async function test2 () {
return Promise.map([
(() => {
throw new Error('Some validation')
})()
])
}
这不会产生未处理的拒绝。