Node.js 我该在哪里抓住这个承诺MongoError?

Node.js 我该在哪里抓住这个承诺MongoError?,node.js,mongodb,mongoose,promise,mongoose-schema,Node.js,Mongodb,Mongoose,Promise,Mongoose Schema,我升级了我的猫鼬,所以我当然开始得到这些: DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html 所以我添加了mongoose.Promise=global.Promise。一切都好。除了现在我知道这家伙

我升级了我的猫鼬,所以我当然开始得到这些:

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library)
is deprecated, plug in your own promise library instead:
http://mongoosejs.com/docs/promises.html
所以我添加了
mongoose.Promise=global.Promise
。一切都好。除了现在我知道这家伙:

(node:20760) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: exception: Index with name: stampRoundedToNearestHour_1 already exists with different options
(node:20760) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
修复潜在错误很容易,但我不知道应该在哪里捕获它,这样将来的Node版本在遇到类似情况时不会突然崩溃。我已经生成了产生错误的代码的最小版本。这是一个javascript文件:

var mongoose = require('mongoose')
mongoose.Promise = global.Promise

var TestSchema = mongoose.Schema({
  num: Number,
})

TestSchema.index({'num': 1}, { sparse: true })
TestSchema.index({'num': 1}, { sparse: false })
// The above line is deliberately designed to be problematic.
// My question isn't how to not get an error,
// it's that I don't know where to catch it when I do!

// If this line is commented out, there's no error
// but it doesn't return a promise, so I can't .then or .catch on it
var Test = mongoose.model('Test', TestSchema)

mongoose.connect(process.env.MONGOLAB_URI, {useMongoClient: true})
.then(function () {
  console.log("mongoose.connected successfully")
}).catch(function (err) {
  console.log("mongoose.connect catch", err)
})
如您所见,我在
mongoose.connect()
函数上尝试了这两种错误处理,但运行此函数时的输出是

mongoose.connected successfully
(node:26795) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: exception: Index with name: num_1 already exists with different options
(node:26795) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
我已经尝试将
.catch(…)
添加到这里的每个其他函数中:

  • mongoose.Schema(…)
  • TestSchema.index({'num':1},{sparse:true})
  • mongoose.model('Test',TestSchema)
  • 甚至
    require('mongoose')
    (这感觉很愚蠢,但我试过了)
…以及我系统中的一些其他功能,我可以在保留代码的同时删除这些功能

但是在所有这些情况下,
TypeError:WHATEVER.catch不是一个函数


我应该在哪里捕捉到这个
MongoError
?(同样,我知道如何防止它)

之所以出现这种情况,是因为定义了重复的索引

您应该只有一行

TestSchema.index({'num': 1}, { sparse: true })
TestSchema.index({'num': 1}, { sparse: false })
未处理的承诺实际上来自与
createIndex
相关的拒绝。这在mongoose中不公开,您无法捕捉错误


可能的逻辑推理是,模式定义中永远不应该有错误。这是一个在开发过程中很容易发现的问题,以后不会再重复。

在仔细查看并发现后,这个问题的一个可能答案是添加以下行:

process.on('unhandledRejection', function(error) {
  // do something with this error
})
这样做意味着此警告消失:

(node:26795) [DEP0018] DeprecationWarning: Unhandled promise rejections 
are deprecated. In the future, promise rejections that are not handled 
will terminate the Node.js process with a non-zero exit code.

但我并不知道这会阻止Node.js进程退出。

使用
。然后(successFunction,errorFunction)
某种程度上禁止了
.catch()
,这实际上又是
的“糖分”。然后(null,errorFunction)
。这就是产生错误的全部代码吗?您确实“不应该”在“实际连接”之后建立模型,但这并不是真正的错误原因。所以我在这里看到的只是承诺链语法。除非有其他代码?简单地说。只需尝试:
mongoose.connect(process.env.MONGOLAB_URI,{useMongoClient:true}),然后(()=>console.log('connected')).catch(err=>console.error(err))为了它,因为您的现有代码中似乎有未声明的变量,应该抛出“未捕获异常”@NeilLunn是的,我知道。我真是不知所措,因为这就是所有的代码,所以我把
.catch()
卡在
TypeError
允许我的任何地方。这实际上是一个js文件,如果你运行它,它会产生这个错误。不知道你说的未声明变量是什么意思。在现有的代码中,模型是在连接建立之前建立的,我只是尝试将
mongoose.connect(…)
部分放在底部,但它仍然出错。这是不同的。索引定义是错误所在。但这“是一个人为的例子”,除非你在这种情况下特别需要捕捉到那个特定的错误,否则你可以通过不做它来很容易地避免它。事实上,mongoose文档建议您“关闭自动索引”,并使用“特定代码”创建索引。此外,这不是您最初发布的问题。已修复该问题(请参阅编辑的代码),但仍无法捕获错误。原来的语法只是多余的(因为我把af弄糊涂了),其实并没有错。你运行的是什么版本的mongoose?mongoose@4.12.4Yeah,我得到了同样的东西。但实际上,你的应用程序永远不应该这样做。因为您错误地定义了模式,所以在使用之前您总是会修复此错误,并且在您的应用程序运行时不会出现此错误。我还认为,即使您找到了捕获此错误的“解决方案”,将其添加到代码中也是错误的,正如我所说,这是在提交/部署之前必须解决的问题。这不是一个好主意,因为它将适用于应用程序中所有未处理的拒绝。这不是你想要的,因为在大多数情况下,你想要抓住承诺,而不是忽视它们。是的,我基本上同意这是个坏主意。我将使用
process.on('unhandledRejection',…)
功能更好地跟踪此类未处理的弹出,例如通过打印堆栈,如果生产中出现未处理的弹出,也可以通过电子邮件发送给我。