因此,我想知道如何确定如果遇到程序员错误(未定义变量,引用错误,语法错误...),我的Node应用程序将崩溃。但是,如果我使用的是Promise链,那么最后的catch()
将捕获所有可能的错误,包括程序员错误。
例如:
PromiseA()
.then((result) => {
foo.bar(); //UNDEFINED FUNCTION HERE!!!!!
return PromiseB(result);
})
.catch(
//handle errors here
)
现在,catch()
语句还将捕获未定义函数的真正严重错误,然后尝试对其进行处理。当遇到此类错误时,我需要一种使程序崩溃的方法。
编辑:我也刚刚意识到,即使我在最后一个catch中抛出一个错误,它也会被promise链消耗:-[。我应该如何处理?
答案 0 :(得分:1)
基本上,您要做的是处理可能会从中恢复的那些错误。这些错误通常是您在代码中抛出的错误。例如,如果在数据库中找不到某个项目,则某些库将抛出Error
。他们会添加一个type
属性或其他属性来区分不同类型的错误。
您还可以潜在地将Error
类子类化,并使用instanceof
来区分每个错误。
class myOwnError extends Error {}
然后:
Prom.catch(err => {
if(err instanceof myOwnError){ /* handle error here */ }
else { throw err; }
});
如果要避免if / chains,可以在switch
上使用error.constructor
:
switch(err.constructor){
case myOwnError:
break;
case someOtherError:
break;
default:
throw err;
}
您还可以通过为每个可能的错误创建函数并将其存储来使用Map
或常规对象。使用Map
:
let m = new Map();
m.set(myOWnError, function(e){ /*handle error here*/ });
m.set(myOtherError, function(e){ /*handle other error here*/ });
然后就做:
Prom.catch(err => {
let fn = m.get(err.constructor);
if(fn){ return fn(err); }
else { throw err; }
});
答案 1 :(得分:1)
免责声明:以下是我们在我工作的公司所做的描述。链接的程序包是由我们编写的。
我们要做的是捕捉所有错误并将它们分类为程序员和操作错误。
我们已经建立了小型图书馆来帮助我们:https://www.npmjs.com/package/oops-error
对于诺言链,我们使用:
import { programmerErrorHandler } from 'oops-error'
...
export const doSomething = (params) => {
somePromiseFunction().catch(programmerErrorHandler('failed to do something', {params}))
}
将错误标记为程序员错误,将“无法做某事”添加为错误消息,并将参数作为上下文添加(供以后调试)
对于我们知道可能会出现的错误(找不到人,validEmail等),我们执行类似的操作
import { Oops } from 'oops-error'
export const sendEmail = (email) => {
if(!isValidEmail(email)) {
throw new Oops({
message: 'invalid email',
category: 'OperationalError',
context: {
email,
},
})
}
...
}
在每个级别,我们都显示操作错误的错误消息。很简单
.cath(e => {
if (e.category == 'OperationalError') {
// handle the gracefully
}
else {
throw e // We will tackle this later
}
}
在express的请求结尾处,我们有最终的错误处理程序,可以捕获错误,检查其是否可操作,然后显示错误消息,但不显示实际上下文。如果是程序员错误,我们将停止该过程(这不理想,但是我们不希望用户继续弄乱已损坏的代码)