升级到 Mongoose 5.0.13 - 从蓝鸟错误中获得 500 的 angular-fullstack 生成的应用程序:错误:期待一个数组,一个承诺

Posted

技术标签:

【中文标题】升级到 Mongoose 5.0.13 - 从蓝鸟错误中获得 500 的 angular-fullstack 生成的应用程序:错误:期待一个数组,一个承诺【英文标题】:Upgraded to Mongoose 5.0.13 - getting a 500 in angular-fullstack generated app from a bluebird error: Error: expecting an array, a promise 【发布时间】:2018-09-17 01:44:48 【问题描述】:

我有一个应用程序,是我在 同时 之前使用 angular-fullstack 生成器创建的。一切都很好,直到我们需要升级我们的 mongoose 以获得 bulkwrite。好吧,当我们到达 mongoose 4.11.13(或 4.>8。我不记得具体版本但它大于 4.8 并且

TypeError:期待一个数组、一个promise或一个thenable

见https://github.com/petkaantonov/bluebird/wiki/Error:-expecting-an->array,-a-promise-or-a-thenable

PUT /api/accounts/57488f5ac260210300c10d80 500 77.719 毫秒 - 2

这是导致错误的方法:

// Updates an existing Account in the DB
export function update(req, res) 
  if (req.body._id) 
    delete req.body._id;
  
  Account.findByIdAsync(req.params.id)
   .then(handleEntityNotFound(res))
    .then(saveUpdates(req.body))
    .then(responseWithResult(res))
    .catch(handleError(res));

来自样板生成器

我已通过删除其他内容将其缩小到 saveUpdates(req.body)。对数据库的更新会发生并持续存在,但会发现错误。

这是 saveUpdates 方法 - 再次来自生成器。

function saveUpdates(updates) 
  return function(entity) 
    var updated = _.merge(entity, updates);
    return updated.saveAsync()
      .spread(updated => 
        return updated;
      );
  ;

我想我已经接近找到其他接近的解决方案,并且我已经尝试过,但它无助于解决错误。

之前有人遇到过这个问题,或者知道如何重构它以使用最新的 mongoose?

【问题讨论】:

updated.saveAsync() 传递什么,为什么需要传播? 它正在返回更新的记录信息。我不确定为什么需要传播它。它是生成的样板代码的一部分。您对通过猫鼬进行保存的不同方法有什么建议吗? .spread() 将数组转换为参数列表,因此.spread(updated => return updated; ) 是传递.saveAsync() 传递的数组的第一个元素的一种相当复杂的方式。这可能没有错,但这是一种相当奇怪的处理方式。 @Roamer-1888 你知道是否有更好的方法来代替返回承诺?我假设这是问题所在?或者至少我可以放一些东西来返回一个承诺作为测试,看看错误是否消失? 【参考方案1】:

@Roamer-1888 我解决了这个问题。从 angular-fullstack-generator 来看,原始样板代码在 mongoose 5 中不起作用。

原始样板 saveUpdates() 是这样的:

function saveUpdates(updates) 
  return function(entity) 
    var updated = _.merge(entity, updates);
    return updated.saveAsync()
      .spread(updated => 
        return updated;
      );
  ;

基于 pm @Roamer-1888 的注释,我做了以下更改,500 错误消失了:

function saveUpdates(updates) 
  return function(entity) 
    return _.merge(entity, updates).saveAsync()
      .then(updated => updated);
  ;

问题解决了!谢谢@Roamer-1888

【讨论】:

样板版本不起作用,这很奇怪,但这解决了它。我唯一能想到的是,被传递的成员updated 是类似数组的(它有第 0 个元素)。如果它是真正的 Array,那么我认为样板文件会起作用。顺便说一句,工作代码将简化为function saveUpdates(updates) return function(entity) return _.merge(entity, updates).saveAsync().then(updated => updated[0]); ; 它确实有所作为。感谢您提供更简洁的代码,我收到了您的更新。 在进一步的测试中,我发现 [0] 实际上导致调用 api 时的任何 .then() 都不起作用 http.put(/url).then( console.log( '这不起作用'));删除了[0],一切都解决了。还了解到验证器需要从 return respond(true) 更改为仅返回 true - 这些是对旧样板代码的其他小猫鼬 4->5 更新。 在这种情况下,您似乎可以完全删除.then(),留下return _.merge(entity, updates).saveAsync()

以上是关于升级到 Mongoose 5.0.13 - 从蓝鸟错误中获得 500 的 angular-fullstack 生成的应用程序:错误:期待一个数组,一个承诺的主要内容,如果未能解决你的问题,请参考以下文章

蓝鸟承诺:循环猫鼬结果

猫鼬承诺与蓝鸟和打字稿

带有护照js的蓝鸟错误的猫鼬承诺

节点蓝鸟中的 Q.ninvoke 替换

从 v4.13.7 升级到 5.0.1 后节点应用程序崩溃

无法得到我在 nodejs / mongoose / bluebird 中返回的承诺