2

我有一个相当标准的 connect-mongo 设置

猫鼬在此之前初始化/连接

app.use(express.session({
    secret: "sfdgsdgsdfg",
    store: new MongoSessionStore({db: mongoose.connection.db})
}));

这工作正常。

但是 - 假设我的 mongodb 连接突然中断(在下面的示例中本地停止 mongod) - 下次我尝试到达路线时,我的快速应用程序也会崩溃 -

错误:无法在 null 处连接到 [localhost:27017]。(/Users/alex/Projects/MyProject/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:540:74) 在空时发出 (events.js:106:17)。(/Users/alex/Projects/MyProject/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:140:15) 在 Socket 的发射 (events.js:98:17)。(/Users/alex/Projects/MyProject/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:478:10) 在 Socket.emit (events.js:95:17) 在 net.js: 440:14 在 process._tickCallback (node.js:419:13)

有没有办法处理这个错误并(例如)重定向到 /error 路由?(显然是不需要会话的!)

编辑

所以现在,我正在创建一个单独的猫鼬连接。

然后我使用on('error'来监听错误

...这就是我被卡住的地方-该过程仍然死亡,因为重新抛出错误不会将其传递给快速错误处理程序...

var sessionDbConnection = mongoose.createConnection(config.sessionDb);

sessionDbConnection.on('error', function(err) {
    console.log('oops');
    throw err; //instead of re-throwing the error, i think i need to pass it to the error handler below??
})

app.use(express.session({
    secret: "sfdgsdgsdfg",
    store: new MongoSessionStore({db: sessionDbConnection.db})
}));

app.use(function(err, req, res, next) {
    res.render('error', err); //just for testing
});
4

1 回答 1

2

在使用链的末尾设置一个通用错误处理程序...

//function must accept 4 arguments
app.use(function(err, req, res, next) {
  //use accepts to determin if you should return json, html, image?
  //render the appropriate output.
});

(req, res, next)此外,让您的处理程序和其他模块在发生错误时接受三个参数,return next(err)通常您会希望有选择地使用一个.code属性来将您的 http 响应代码与匹配错误的代码相匹配。用于4xx输入错误、5xx服务器错误等。

另外,如果您想处理一般情况...

process.on('uncaughtException', function(err) {
  console.error('Caught exception: ' + err);
  console.error(err.stack);

  //interrogate the error, if it's something you can recover from, let it be.
  //if the exception is fatal, exit with prejudice
  setTimeout(process.exit.bind(process, 666), 1000); //exit in a second
});

这将处理您的特定情况,但您应该只允许该进程继续运行,如果它应该自行恢复。


作为对您的编辑的回应...当您收到数据库错误时,您可能有一个全局变量会更改...不幸的是,此错误不一定发生在 http 请求的上下文中..它可能发生在之前/期间/之后……这样,你就无法知道了。

如果您使用的客户端会在失败时重新连接,那么这将缓解一些问题。您能做的最好的事情就是跟踪这个变量,为所有请求提供错误..然后重新启动您的流程。

有很多模块pm2可以forever帮助你解决这个问题。

于 2014-11-26T00:28:40.773 回答