JavaScript尝试/捕获:错误还是异常?

时间:2022-10-28 13:27:34

OK. I may be splitting hairs here, but my code isn't consistent and I'd like to make it so. But before I do, I want to make sure I'm going the right way. In practice this doesn't matter, but this has been bothering me for a while so I figured I'd ask my peers...

好的。我可能在这里吹毛求疵,但是我的代码不一致,我想这样做。但在此之前,我要确保我的方向是正确的。实际上这并不重要,但这已经困扰了我一段时间,所以我想我应该问问我的同伴……

Every time I use a try... catch statement, in the catch block I always log a message to my internal console. However my log messages are not consistent. They either look like:

每次我尝试……catch语句,在catch块中,我总是将消息记录到内部控制台。但是我的日志消息不一致。他们要么看起来像:

catch(err) {
DFTools.console.log("someMethod caught an error: ",err.message);
...

or:

或者:

catch(ex) {
DFTools.console.log("someMethod caught an exception: ",ex.message);
...

Obviously the code functions properly either way but it's starting to bother me that I sometimes refer to "errors" and sometimes to "exceptions". Like I said, maybe I'm splitting hairs but which is the proper terminology? "Exception", or "Error"?

显然,这两种方式的代码都能正常运行,但我有时会提到“错误”,有时也会提到“异常”,这让我感到困扰。就像我说的,也许我在吹毛求疵,但这是恰当的术语?“异常”或“错误”?

6 个解决方案

#1


11  

This is a bit subjective, but to me an error is when someone or something does something wrong, improper, or invalid. It could be a syntax error, a logical error, a read error, user error, or even a social error. It's an abstract concept.

这有点主观,但对我来说,错误是当某人或某事做错了、不适当或无效的时候。它可能是语法错误、逻辑错误、读取错误、用户错误,甚至是社会错误。这是一个抽象的概念。

An exception, on the other hand, is an object that is created and thrown when a certain condition occurs in code. It may or may not correspond to a conceptual error. So to me, the proper nomenclature is "exception".

另一方面,异常是在代码中出现某种条件时创建和抛出的对象。它可能与概念上的错误相符,也可能不相符。所以对我来说,恰当的命名法是“例外”。

#2


4  

The ECMAScript specification calls them exceptions. You might want to do likewise.

ECMAScript规范将它们称为异常。你也可以这样做。

To make your logging more informative:

让你的日志更有信息价值:

catch(ex) {
    DFTools.console.log("someMethod caught an exception of type " 
       + ex.name + ": ", ex.message);

You might also want to bear in mind that exceptions (unfortunately) can be of any type, and so don't necessarily have name and message properties:

您可能还需要记住,异常(不幸的是)可以是任何类型的,所以不一定要有名称和消息属性:

catch(ex) {
    if (ex.message && ex.name) {        
        DFTools.console.log("someMethod caught an exception of type " 
           + ex.name + ": ", ex.message);
    } else /* deal with it somehow */

As this is starting to look pretty cumbersome to repeat everywhere, you might want to capture it in a function:

由于在任何地方重复这个操作看起来都很麻烦,您可能想要在函数中捕获它:

function logExceptions(methodName, action) {

    try {

        action();

    } catch (ex) {
        if (ex.message && ex.name) {        
            DFTools.console.log("someMethod caught an exception of type " 
               + ex.name + ": ", ex.message);
        } else {
            DFTools.console.log("someMethod caught a poorly-typed exception: " + ex);
        }
    }
}

Now you can say:

现在你可以说:

logExceptions(function() {

    // do some risky stuff...

});

#3


1  

In JavaScript it is called Error Catching. So I would suggest you use error instead of exception. Leave the choice in the middle by using "e". Like in the examples of Mozilla. Mozilla Core JavaScript 1.5 Reference

在JavaScript中,它被称为错误捕获。所以我建议你使用错误而不是异常。使用“e”将选项放在中间。就像Mozilla的例子一样。Mozilla核心JavaScript 1.5参考。

#4


1  

Exception is something you may expected for example in an attempt to open a file may face a "File not found exception". On the other hand, errors are something you may not see it coming like stack over flow or not enough memory.

异常是您可能期望的,例如,在试图打开文件时,可能会遇到“未找到异常”。另一方面,错误是一些您可能看不到的东西,比如堆/流或内存不足。

An exception is an alternative logical way out off a function that does not produce a logical result. An exception also allows a better explanation of what happen why it exist this way. For File opening, again, a file handle is a logical result and if the file is not exist (one possible exception) or it is a folder not a file (another possible exception).

异常是一种可选的逻辑方法,可以从一个不产生逻辑结果的函数中提取出来。异常还可以更好地解释为什么会发生这种情况。对于文件打开,同样,文件句柄是一个逻辑结果,如果文件不存在(一个可能的异常),或者它是一个文件夹而不是文件(另一个可能的异常)。

#5


1  

MAJOR DISCLAIMER: I don't consider that there is a "right" answer to this. The views expressed here are subjective and personal. What's more is that the ideas I'm about to espouse are only useful if you are going to do different things with different, ahem, faults... as you might using a system as per Daniel Earwicker's informative answer. With that in mind:

主要免责声明:我不认为这有一个“正确”的答案。这里所表达的观点是主观的和个人的。更重要的是,我将要支持的想法只有当你要用不同的,呃,错误做不同的事情时才有用。正如你可能会使用一个系统,根据Daniel Earwicker的信息。记住这一点:

I contend that "an EXCEPTION is exceptional". An ERROR is less unexpected.

我认为“例外是例外”。错误就不那么意外了。

disclaimer: The following pseudo-code is not good; it merely serves as the minimum case I could think of to illustrate my point.

免责声明:以下伪代码不好;它只是作为我能想到的最简单的例子来说明我的观点。

note: in this thought experiment, GetFile returns UNDEFINED if it cannot find the specified file.

注意:在这个思想实验中,如果无法找到指定的文件,GetFile返回未定义的文件。

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;
}

In the case that a consumer calls GetFileOrThrow with a filename that doesn't exist, an ERROR will occur. To my mind the distinction is really that higher-level code (or user input) is doing something wrong... this function must pass an ERROR up the line to that higher-level code which can decide what to do about this result. Consider it like this... this function would be saying to any consuming functions:

如果使用者调用GetFileOrThrow时文件名不存在,则会发生错误。在我看来,真正的区别在于高级代码(或用户输入)做错了什么……这个函数必须将错误传递到更高级别的代码中,从而决定如何处理这个结果。考虑这样……这个函数会对任何消费函数说:

Look, my friend, I know what's going on here: it is an ERROR to request BobAccounts.xml, so don't do it again! Oh, and if you think you now know what might have gone wrong (having abused me), go ahead and try to recover from it!

听着,我的朋友,我知道这是怎么回事:请求BobAccounts是错误的。xml,所以不要再这样做了!哦,如果你认为你现在知道可能出了什么问题(曾经虐待过我),那就去试着从它中恢复过来吧!

Now consider the case that this function takes the name, checks that the file exists and then for some reason fails to retrieve it. This is a different situation. Something really unexpected has happened. What's more, the consuming code isn't to blame. Now we really want this function to say to any consuming functions:

现在考虑这样的情况:该函数接受名称,检查文件是否存在,然后由于某种原因无法检索它。这是另一种情况。发生了意想不到的事情。更重要的是,消费代码不是罪魁祸首。现在我们真的想让这个函数对任何消费函数说:

Oh fiddlesticks! Sorry about this, I humbly beg your pardon but something EXCEPTIONAL that I don't really understand has gone wrong. I don't think that your request for BobAccounts.xml was unreasonable... and I know I should be fulfilling it for you. Since I'm lower level code than you, I really ought to know what's going on... but I don't... and since you've less chance than me of understanding this EXCEPTIONAL situation, I think you'd probably best just stop what you're doing and let this message go all the way to the top... I mean, there is something seriously fishy going on here.

哦,胡说!很抱歉,我很抱歉地请求您的原谅,但是我不太理解的一些特殊的地方出了问题。我不认为你要的是BobAccounts。xml是不合理……我知道我应该为你实现它。因为我的级别比你低,所以我真的应该知道发生了什么……但我不…既然你比我更少了解这种特殊情况,我认为你最好停止你正在做的事情,让这条信息一直延伸到顶端……我是说,这里有严重的问题。

So I suppose my summary is this: If the mistake happened in higher order code (you were passed bad data) throw an ERROR. If the mistake happened in lower order code (a function you depended on failed in a way you didn't understand and couldn't plan for) throw an EXCEPTION... and if the mistake happened in the function you are currently writing... well, duh, if you're aware of it then fix it!

因此,我的总结是:如果错误发生在高阶代码中(您被传递了错误数据),则抛出一个错误。如果错误发生在较低的代码中(您所依赖的函数以一种您不理解且无法计划的方式失败)抛出异常……如果你正在编写的函数中出现了错误……哦,对了,如果你意识到了,那就把它修好!

And, finally, to answer the original question more directly: In terms of handling ERRORS and EXCEPTIONS, my advice would be: Handle all ERRORS gracefully (optionally logging them)... but handle EXCEPTIONS carefully indeed; only try to recover from an EXCEPTION if you are really sure you know what it is and why it's happened, otherwise let it bubble up (rethrowing it if you have to).

最后,为了更直接地回答最初的问题:就处理错误和异常而言,我的建议是:优雅地处理所有错误(可选地记录它们)……但要谨慎处理例外情况;只有当你真的确定你知道它是什么以及它发生的原因时,才尝试从一个异常中恢复,否则就让它冒出来(如果有必要的话,重新抛出)。

#6


0  

What you get in a Catch block is an Exception, so I name it as an exception...

在Catch块中得到的是一个异常,因此我将它命名为一个异常……

If it is an error - I can handle it in my code & I usually don't expect to see it in the Catch block

如果是错误——我可以在代码中处理它&我通常不会期望在Catch块中看到它

HTH.

HTH。

#1


11  

This is a bit subjective, but to me an error is when someone or something does something wrong, improper, or invalid. It could be a syntax error, a logical error, a read error, user error, or even a social error. It's an abstract concept.

这有点主观,但对我来说,错误是当某人或某事做错了、不适当或无效的时候。它可能是语法错误、逻辑错误、读取错误、用户错误,甚至是社会错误。这是一个抽象的概念。

An exception, on the other hand, is an object that is created and thrown when a certain condition occurs in code. It may or may not correspond to a conceptual error. So to me, the proper nomenclature is "exception".

另一方面,异常是在代码中出现某种条件时创建和抛出的对象。它可能与概念上的错误相符,也可能不相符。所以对我来说,恰当的命名法是“例外”。

#2


4  

The ECMAScript specification calls them exceptions. You might want to do likewise.

ECMAScript规范将它们称为异常。你也可以这样做。

To make your logging more informative:

让你的日志更有信息价值:

catch(ex) {
    DFTools.console.log("someMethod caught an exception of type " 
       + ex.name + ": ", ex.message);

You might also want to bear in mind that exceptions (unfortunately) can be of any type, and so don't necessarily have name and message properties:

您可能还需要记住,异常(不幸的是)可以是任何类型的,所以不一定要有名称和消息属性:

catch(ex) {
    if (ex.message && ex.name) {        
        DFTools.console.log("someMethod caught an exception of type " 
           + ex.name + ": ", ex.message);
    } else /* deal with it somehow */

As this is starting to look pretty cumbersome to repeat everywhere, you might want to capture it in a function:

由于在任何地方重复这个操作看起来都很麻烦,您可能想要在函数中捕获它:

function logExceptions(methodName, action) {

    try {

        action();

    } catch (ex) {
        if (ex.message && ex.name) {        
            DFTools.console.log("someMethod caught an exception of type " 
               + ex.name + ": ", ex.message);
        } else {
            DFTools.console.log("someMethod caught a poorly-typed exception: " + ex);
        }
    }
}

Now you can say:

现在你可以说:

logExceptions(function() {

    // do some risky stuff...

});

#3


1  

In JavaScript it is called Error Catching. So I would suggest you use error instead of exception. Leave the choice in the middle by using "e". Like in the examples of Mozilla. Mozilla Core JavaScript 1.5 Reference

在JavaScript中,它被称为错误捕获。所以我建议你使用错误而不是异常。使用“e”将选项放在中间。就像Mozilla的例子一样。Mozilla核心JavaScript 1.5参考。

#4


1  

Exception is something you may expected for example in an attempt to open a file may face a "File not found exception". On the other hand, errors are something you may not see it coming like stack over flow or not enough memory.

异常是您可能期望的,例如,在试图打开文件时,可能会遇到“未找到异常”。另一方面,错误是一些您可能看不到的东西,比如堆/流或内存不足。

An exception is an alternative logical way out off a function that does not produce a logical result. An exception also allows a better explanation of what happen why it exist this way. For File opening, again, a file handle is a logical result and if the file is not exist (one possible exception) or it is a folder not a file (another possible exception).

异常是一种可选的逻辑方法,可以从一个不产生逻辑结果的函数中提取出来。异常还可以更好地解释为什么会发生这种情况。对于文件打开,同样,文件句柄是一个逻辑结果,如果文件不存在(一个可能的异常),或者它是一个文件夹而不是文件(另一个可能的异常)。

#5


1  

MAJOR DISCLAIMER: I don't consider that there is a "right" answer to this. The views expressed here are subjective and personal. What's more is that the ideas I'm about to espouse are only useful if you are going to do different things with different, ahem, faults... as you might using a system as per Daniel Earwicker's informative answer. With that in mind:

主要免责声明:我不认为这有一个“正确”的答案。这里所表达的观点是主观的和个人的。更重要的是,我将要支持的想法只有当你要用不同的,呃,错误做不同的事情时才有用。正如你可能会使用一个系统,根据Daniel Earwicker的信息。记住这一点:

I contend that "an EXCEPTION is exceptional". An ERROR is less unexpected.

我认为“例外是例外”。错误就不那么意外了。

disclaimer: The following pseudo-code is not good; it merely serves as the minimum case I could think of to illustrate my point.

免责声明:以下伪代码不好;它只是作为我能想到的最简单的例子来说明我的观点。

note: in this thought experiment, GetFile returns UNDEFINED if it cannot find the specified file.

注意:在这个思想实验中,如果无法找到指定的文件,GetFile返回未定义的文件。

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;
}

In the case that a consumer calls GetFileOrThrow with a filename that doesn't exist, an ERROR will occur. To my mind the distinction is really that higher-level code (or user input) is doing something wrong... this function must pass an ERROR up the line to that higher-level code which can decide what to do about this result. Consider it like this... this function would be saying to any consuming functions:

如果使用者调用GetFileOrThrow时文件名不存在,则会发生错误。在我看来,真正的区别在于高级代码(或用户输入)做错了什么……这个函数必须将错误传递到更高级别的代码中,从而决定如何处理这个结果。考虑这样……这个函数会对任何消费函数说:

Look, my friend, I know what's going on here: it is an ERROR to request BobAccounts.xml, so don't do it again! Oh, and if you think you now know what might have gone wrong (having abused me), go ahead and try to recover from it!

听着,我的朋友,我知道这是怎么回事:请求BobAccounts是错误的。xml,所以不要再这样做了!哦,如果你认为你现在知道可能出了什么问题(曾经虐待过我),那就去试着从它中恢复过来吧!

Now consider the case that this function takes the name, checks that the file exists and then for some reason fails to retrieve it. This is a different situation. Something really unexpected has happened. What's more, the consuming code isn't to blame. Now we really want this function to say to any consuming functions:

现在考虑这样的情况:该函数接受名称,检查文件是否存在,然后由于某种原因无法检索它。这是另一种情况。发生了意想不到的事情。更重要的是,消费代码不是罪魁祸首。现在我们真的想让这个函数对任何消费函数说:

Oh fiddlesticks! Sorry about this, I humbly beg your pardon but something EXCEPTIONAL that I don't really understand has gone wrong. I don't think that your request for BobAccounts.xml was unreasonable... and I know I should be fulfilling it for you. Since I'm lower level code than you, I really ought to know what's going on... but I don't... and since you've less chance than me of understanding this EXCEPTIONAL situation, I think you'd probably best just stop what you're doing and let this message go all the way to the top... I mean, there is something seriously fishy going on here.

哦,胡说!很抱歉,我很抱歉地请求您的原谅,但是我不太理解的一些特殊的地方出了问题。我不认为你要的是BobAccounts。xml是不合理……我知道我应该为你实现它。因为我的级别比你低,所以我真的应该知道发生了什么……但我不…既然你比我更少了解这种特殊情况,我认为你最好停止你正在做的事情,让这条信息一直延伸到顶端……我是说,这里有严重的问题。

So I suppose my summary is this: If the mistake happened in higher order code (you were passed bad data) throw an ERROR. If the mistake happened in lower order code (a function you depended on failed in a way you didn't understand and couldn't plan for) throw an EXCEPTION... and if the mistake happened in the function you are currently writing... well, duh, if you're aware of it then fix it!

因此,我的总结是:如果错误发生在高阶代码中(您被传递了错误数据),则抛出一个错误。如果错误发生在较低的代码中(您所依赖的函数以一种您不理解且无法计划的方式失败)抛出异常……如果你正在编写的函数中出现了错误……哦,对了,如果你意识到了,那就把它修好!

And, finally, to answer the original question more directly: In terms of handling ERRORS and EXCEPTIONS, my advice would be: Handle all ERRORS gracefully (optionally logging them)... but handle EXCEPTIONS carefully indeed; only try to recover from an EXCEPTION if you are really sure you know what it is and why it's happened, otherwise let it bubble up (rethrowing it if you have to).

最后,为了更直接地回答最初的问题:就处理错误和异常而言,我的建议是:优雅地处理所有错误(可选地记录它们)……但要谨慎处理例外情况;只有当你真的确定你知道它是什么以及它发生的原因时,才尝试从一个异常中恢复,否则就让它冒出来(如果有必要的话,重新抛出)。

#6


0  

What you get in a Catch block is an Exception, so I name it as an exception...

在Catch块中得到的是一个异常,因此我将它命名为一个异常……

If it is an error - I can handle it in my code & I usually don't expect to see it in the Catch block

如果是错误——我可以在代码中处理它&我通常不会期望在Catch块中看到它

HTH.

HTH。