2016-08-18 89 views
1

处理我有一个非常基本的迁移代码看起来像这样。它删除表格,创建表格,并用一些数据对其进行种子处理。正确与错误的NodeJS /快速

this.knex.schema.dropTable(this.tableName) 
.catch((err) => console.log(err)) 
.then(() => { 
    this.knex.schema.createTable(this.tableName, function(table) { 
     table.increments("id").primary(); 
     table.string("name"); 
     table.integer("parent_id").unsigned().default(0); 
    }) 
    .catch((err) => console.log(err)) 
    .then(() => { 
     this.categories.forEach((category) => { 
      Category.create(category) 
      .catch((err) => console.log(err)) 
      .then((category) => console.log(category.get("name") + " seeded.")) 
     }); 
    }); 
}); 

您可能注意到,代码上有3x .catch((err) => console.log(err))链。

现在我有Bugsnag集成到我的应用程序,我想确保我正确登录所有异常/上Bugsnag错误,所以我可以修复所有的错误。但是,现在我所能做的就是将它们登录到控制台中。更糟糕的是,我重复自己并重复每个catch块的逻辑。

我在考虑做这样的事情:

.catch((err) => ErrorHandler.add(err)) 

class ErrorHandler { 

    add(err) { 
     // Notify Bugsnag 
     // Log it to console 
    } 

} 

这abrings另一个问题。如果我忘记添加catch方法,那么它将不起作用。

想过做这样的事情,太:

// Change exception behaviour so whenever they are called, they raise an `onException` event 
app.listen("onException", (err) => { 
    // Notify Bugsnag 
    // Log error to console 
}); 

这样我可以捕获所有的错误和干我的代码,但我不知道,如果节点支持挂钩例外。

你会在我的情况,我应该采取什么样的方式做什么?我想确保所有错误都正确发送到Bugsnag。

回答

1

首先,确实this.knex.schema.createTable返回一个承诺? (如果没有,你可以随时将其转换回一个承诺),如果是的话,你可以在一点点更清洁的方式写这个逻辑,如:

this.knex.schema.dropTable(this.tableName) 
.then((...) => { 
    ... 
    return this.knex.schema.createTable(...) 
}) 
.then((...) => { 
... // do whatever you are doing with table object 
    return Promise.all(map and do whatever you are doing with categories) 
}) 
.then(() => { 
    // log that everything went well with seeding 
}) 
.catch((err) => { 
    // single catch block to handle errors from this promise chain 
}) 

Promise.all将返回拒绝承诺如果从阵列中的任何承诺拒绝,如果你发现这不符合你的需求,你可以使用蓝鸟.reflect()(原生承诺支持节点没有,http://bluebirdjs.com/docs/api/reflect.html

第二,而不是console.log(console.error或其他),你可以考虑使用像本仁,https://github.com/trentm/node-bunyan

三,一般来说,你总是需要捍卫你的应用程序对uncaughtException,像

process.on('uncaughtException', (err) => { 
    ... 
}) 

如果我忘了添加捕捉方法

从我的角度来看,这将是在代码中的bug,你需要知道那个。 像你忘了处理回调错误,比如它是一样的:

doSomething((err, data) => { 
    // do something with data without checking against err 
}) 

所以同样的问题可以问,What if I forget to check against err,以及简单地说,你不处理错误。根据经验,不要只测试晴天情景,就像一切顺利。测测你的代码的不同场景,包括雨天场景中,一些将抛出,确保您处理它以适当的方式。

另外还有一件事你可以受益,你在你的问题中提到Express。您可以注册,你需要的所有路由,如后定义全局错误处理程序:

app.use((err, req, res, next) => { 
    ... 
}) 

有了这个,从任何路线,你可以通过return next(err)通过你的错误该处理器(如果一些特殊的错误处理逻辑,是不是特定于特定端点),确保您可以从中处理错误(例如日志错误),并返回500以及一些消息或其他内容。 https://expressjs.com/en/guide/error-handling.html

+0

感谢您的惊人答案。如果createTable不返回承诺,我如何转换它以返回承诺?此外,蓝鸟究竟是什么,它如何理解数组映射的完成?现在它只是一堆不同的'保存(...),然后(...)'承诺。我想我很快就必须阅读有关承诺。你有什么建议吗? – Aris

+0

你的猜测是正确的,你应该首先熟悉承诺,这真的可以帮助:https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html – Srle

+0

我收获了它。它回答了我的大部分问题。但是,我不知道我怎么能promisify这一个:'this.knex.schema.createTable'。另外,未来如果我需要提出一些不能兑现承诺的东西,我该怎么做?重写该方法并返回'Promise.something()'? – Aris