主要免责声明:我不认为有一个“正确”的答案。这里表达的观点是主观的和个人的。更重要的是,我将要支持的想法只有在你打算用不同的、咳咳、错误的方式做不同的事情时才有用……因为你可能会根据 Daniel Earwicker 的信息性回答使用系统。考虑到这一点:
我认为“例外是例外”。ERROR 不太出人意料。
免责声明:以下伪代码不好;它只是作为我能想到的最小案例来说明我的观点。
注意:在这个思想实验中,GetFile 如果找不到指定的文件,则返回 UNDEFINED。
function AlwaysGetFile(name){
var file = null;
if(FileExists(name)){
file = GetFile(name);
if(typeof file === "undefined"){
throw new "couldn't retrieve file" EXCEPTION
}
}
else{
throw new "file does not exist" ERROR
}
return file;
}
如果消费者使用不存在的文件名调用 GetFileOrThrow,则会发生错误。在我看来,区别实际上是更高级别的代码(或用户输入)做错了什么......这个函数必须将一个错误传递给可以决定如何处理这个结果的更高级别的代码。像这样考虑它......这个函数会对任何消费函数说:
听着,我的朋友,我知道这里发生了什么:请求 BobAccounts.xml 是一个错误,所以不要再这样做了!哦,如果您认为您现在知道可能出了什么问题(虐待了我),请继续尝试从中恢复!
现在考虑这个函数取名字的情况,检查文件是否存在,然后由于某种原因无法检索它。这是一个不同的情况。真的发生了意想不到的事情。更重要的是,消费代码不应该受到责备。现在我们真的希望这个函数对任何消费函数说:
哦,提琴手!对此感到抱歉,我谦虚地请求您的原谅,但是我不太明白的一些特别的事情出了问题。我不认为您对 BobAccounts.xml 的请求是不合理的......而且我知道我应该为您完成它。由于我的代码级别比你低,我真的应该知道发生了什么……但我不知道……而且由于你理解这种特殊情况的机会比我少,我想你可能会最好停止你正在做的事情,让这条信息一直到顶部......我的意思是,这里发生了一些严重的可疑事件。
所以我想我的总结是这样的:如果错误发生在高阶代码中(你传递了错误的数据)抛出一个错误。如果错误发生在低阶代码中(您依赖的函数以您不理解且无法计划的方式失败)抛出异常......并且如果错误发生在您当前正在编写的函数中...... . 好吧,呃,如果你知道它然后修复它!
最后,更直接地回答最初的问题:在处理错误和异常方面,我的建议是:优雅地处理所有错误(可选地记录它们)......但确实要小心处理异常;仅当您确定自己知道它是什么以及为什么会发生时,才尝试从异常中恢复,否则让它冒泡(如果必须重新抛出它)。