我有一个奇怪的情况,我想知道如何解决。 在我的应用程序中,在使用promises的函数之后发生的错误会被抛出,并且app会停止。
这里有一个例子:
getTenant = (req) ->
deferred = Q.defer()
deferred.resolve('foo') if req.info.referrer
deferred.resolve('bar') if !req.info.referrer
deferred.promise
Routes =[
{
method: 'GET'
path: '/'
handler: (request, reply) ->
getTenant(request).then (tenant) ->
console.log 'tenant', tenant
# here `User` is not defined and doesn't even exist
# why is there no error here?
if !User.isAuthorized(request, tenant)
reply 'not authorized'
else
reply 'authorized'
}
]
getTenant
之后{p} User
调用一个函数
User
不存在或导入,但应用程序没有给我任何错误
那是为什么?
当然,如果我将代码包装在try/catch
中,我会抓住错误,但这不是重点。我希望代码实际上会破坏并抛出错误。
这里是完整的示例应用:https://github.com/aschmid/hapierrortest
谢谢你, 安德烈亚斯答案 0 :(得分:1)
简短的回答是因为您忽略了包含错误处理程序。 Promise总是需要成功和错误处理功能。
这是承诺的基本(通常是好的)方面。在promise处理程序内(成功或错误),任何抛出的错误都不会触及窗口。相反,promise实现在内部包装try
块中的promise处理程序,并且在捕获时,拒绝.then
返回的promise。为什么?这样您就可以选择何时何地以及如何处理错误。这就是为什么你可以在一个长的保证链的末尾放一个catch(errHandler)
(这是.then(null, errHandler)
的糖):
somePromise.then(function s1 (val1){
// use val1, return something (e.g. a new promise)
}).then(function s2 (val2){
// use val2, return something (e.g. a new promise)
}).then(function s3 (val3){
// use val3, return something (e.g. a new promise)
}).catch(function e1 (err1){
// handle e1 as you like (console.log, render something on the UI, etc.)
});
在上述链中,somePromise
,s1
,s2
或s3
发生的错误将在e1
处理。这非常好,比在链的每一步都明确处理潜在错误更好。如果你愿意,你仍然可以在每一步处理错误,但它根本不需要。
一般情况下,如果您承诺以某种方式处理错误,那么您根本不想让错误导致应用崩溃。但是如果由于某种原因你想要将错误重新抛出到外部范围,那么你必须使用一个允许重新抛出的最终方法的promise库。例如,Q库中的.done()
。
答案 1 :(得分:-1)
我首先要说我从未使用过Hapi,但你的语法看起来很好......除了...
如果req.info
为空,则会引发异常。试试这个
deferred.resolve('foo') if req.info && req.info.referrer
deferred.resolve('bar') if !req.info || !req.info.referrer