Sequelize findOrCreate() -- .catch() 块在没有错误期间在 spread() 之后执行
Posted
技术标签:
【中文标题】Sequelize findOrCreate() -- .catch() 块在没有错误期间在 spread() 之后执行【英文标题】:Sequelize findOrCreate() -- .catch() block executed after spread() during no error 【发布时间】:2016-09-06 21:28:26 【问题描述】:我的错误类似于这个post:
使用 sequelize.js 作为 ORM 处理程序。 queryCondition 变量值:where: $or: [username:user.username,email:user.email],defaults:user
问题:成功将用户实例保存到数据库后,调用findOrCreate()
后按推荐调用spread()
。 spread()
中的功能块被调用,然后在.catch()
块被调用之后立即被调用。不知道为什么会这样。有人可以帮忙吗?
model.User.findOrCreate(queryCondition).spread(function(user, created)
callback && callback(user, created);
).catch(function(error)
callback && callback(null, null, error);
);
【问题讨论】:
您可以在您的问题中输入 queryCondition 变量吗? where: $or: [username:user.username, email:user.email],defaults:user 听起来您的callback
确实引发了异常。 error
是什么?
对于此类情况,您需要使用then(onFulfilled, onRejected)
pattern 而不是.then(…).catch(…)
。或者,鉴于 Sequelize 使用 Bluebird,请查看 asCallback
(尽管它使用节点回调约定,而不是您的自定义参数顺序)。
没有错误。数据插入成功,但 .catch() 块在之后立即执行
【参考方案1】:
找到答案: Sequelize 使用 Bluebird.js 作为它的 promise 库(查看 package.json 文件)。 documentation 解释了 spread() 方法,推荐在 sequelize 3.0 中使用(参见 post)。本文档中的一个部分指出,spread() 在幕后调用 all().then(..)。因此,以下更改使用 Node.js 解决了我的问题:
model.User.findOrCreate(queryCondition)
.all().then(function(result, isCreated)
callback && callback(null, result, isCreated);
,
function(error)
callback && callback(error);
);
正确解析的 Promise 不会落入错误块中,并且实际的数据库错误会被捕获在错误块中。最后,对于那些认为错误是由于回调参数引起的人,请注意,我只是根据下面 num8er 的建议对回调参数进行了重新排序。 :) 希望这对其他人有所帮助。
【讨论】:
您现在使用三个参数调用callback
,而不是像您在原始问题中那样使用两个参数。我的猜测是 that 实际上解决了您的问题,而不是重写为.all().then()
。在您的初始代码中,回调很可能引发异常(如@Bergi 建议的那样),因为它认为发生了错误,这就是触发catch
的原因(我假设回调执行if (err) throw err
或类似的东西)。
我根据下面 num8er 的建议切换了我的 callback() 的参数顺序以匹配约定...切换参数不是我的错误的原因。【参考方案2】:
如果它正在调用.catch
块,那么它似乎有一些问题。
尝试调试一下,看看原因:
model.User.findOrCreate(queryCondition).spread(function(user, created)
callback && callback(user, created);
).catch(function(error)
console.error(queryCondition, error); // add this and check the output
callback && callback(null, null, error);
);
我还看到您的 queryCondition 变量也可以。
where:$or: [username:user.username,email:user.email],
defaults:user
让我们试试这个注解:
where:$or: [username: $eq: user.username,email: $eq: user.email],
defaults:user
阅读:http://docs.sequelizejs.com/en/latest/docs/querying/#where
如果使用另一个注释,它将无法正常工作,因此我建议您检查表列中的 null
、not null
字段并将其与 user
对象进行比较,以查看 @987654329 中是否缺少字段@ 目的。
在阅读了 Bergi 的评论后,我也建议您尝试这样做:
model.User
.findOrCreate(queryCondition)
.then(
function(result, isCreated)
callback && callback(result, isCreated);
,
function(error)
callback && callback(null, null, error);
);
如果是spread
方法,我认为它不会抛出可捕获的异常,所以在这种情况下:
model.User
.findOrCreate(queryCondition)
.spread(function(result, isCreated)
if(!result)
return callback && callback('Cannot create user');
callback && callback(null, result, isCreated);
);
附:通常在大多数包中,将错误作为回调的第一个参数返回是惯例。所以我只能猜测这个问题不会发生在你的代码示例中,它发生在等待回调的某个地方。
所以尝试像这样修改回调:
callback(user, created); => callback(null, user, created);
callback(null, null, error); => callback(error);
【讨论】:
感谢您的订购建议。我一定会重构...我还添加了查询条件 JSON 变量。 @jried 我已经更新了我的答案,请检查您的表格列是否有关于必填字段的约束,我可以猜测您的用户对象中没有一些非空字段 尝试了两件事:1.添加第三个参数 .spread(function(error, user, created) ... 然后打印变量内容:Spread返回的变量只有两个。2.删除.catch() 语句,如果实际上插入数据时出错,这会导致异常本质上,findOrCreate 成功插入数据,然后我将对象取回......由于某种原因,在成功解析后仍会立即调用 .catch()。 @jried 我没有更改传播参数 ))) 再次你可以在 catch 块内执行 console.log(error) 吗? @jried 我已经更新了我的答案并添加了 Bergi 的提议,试试吧。以上是关于Sequelize findOrCreate() -- .catch() 块在没有错误期间在 spread() 之后执行的主要内容,如果未能解决你的问题,请参考以下文章
Sequelize findOrCreate() -- .catch() 块在没有错误期间在 spread() 之后执行
续集 findOrCreate 插入新行但返回未定义主键的对象
在 Sequelize 中使用 .create(...) 方法时如何处理错误