Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 抛出字符串而不是错误_Javascript - Fatal编程技术网

Javascript 抛出字符串而不是错误

Javascript 抛出字符串而不是错误,javascript,Javascript,既然我们可以在Javascript中抛出任何带有throw关键字的东西,我们就不能直接抛出一个错误消息字符串吗 有人知道这里面有什么陷阱吗 让我添加一些背景知识:在JavaScript世界中,人们通常依赖于参数检查,而不是使用try-catch机制,因此只使用throw抛出致命错误是有意义的。尽管如此,为了能够捕获一些系统错误,我必须为自己的错误使用不同的类,而不是创建错误的子类,我认为我应该只使用String。您可以通过消息抛出错误,您知道 try { throw new Error(

既然我们可以在Javascript中抛出任何带有
throw
关键字的东西,我们就不能直接抛出一个错误消息字符串吗

有人知道这里面有什么陷阱吗


让我添加一些背景知识:在JavaScript世界中,人们通常依赖于参数检查,而不是使用try-catch机制,因此只使用
throw
抛出致命错误是有意义的。尽管如此,为了能够捕获一些系统错误,我必须为自己的错误使用不同的类,而不是创建错误的子类,我认为我应该只使用String。

您可以通过消息抛出错误,您知道

try {
    throw new Error("This is an error");
} catch (e) {
    alert(e.message); // This is an error
}
但实际上,您可以抛出字符串:

try {
    throw "This is an error";
} catch (e) {
    alert(e); // This is an error
}
虽然可以抛出任何值,但通常认为抛出除
Error
或其子类之外的任何值都是不好的。这有几个原因:

  • 捕获代码可能期望抛出的对象具有通常出现在
    错误上的
    消息
    堆栈跟踪
    名称
    属性
  • 缺少stacktrace会导致调试出现问题,特别是在未捕获异常/未处理拒绝的情况下。例如,调试“未捕获的[对象]”错误可能特别痛苦
  • 是的,你,但是

    有人知道这里面有什么陷阱吗

    字符串不是错误对象,并且不传递任何有用的调试信息。Devtools依赖于此,例如创建错误的文件和行、抛出位置的stacktrace等,它们作为
    错误
    对象的属性提供


    每当你想抛出一个基本字符串值时,就抛出一个新的错误(“”

    正如上面其他人所提到的,如果你没有抛出一个错误对象,那么你必须有try/catch块来捕获这些对象并适当地处理它们,否则调试就会受到伤害

    然而,当涉及到为控制程序流等非错误处理目的抛出错误时,这可能是一种利用
    throw
    而不产生错误的有用方法

    当使用抛出来控制程序流时,在任何语言中都可能是低效的,因为运行时通常会做很多繁重的工作来释放调用堆栈信息并序列化数据,以使其可供用户使用。通过避免错误创建,您可以避免这种性能损失。关键是,您必须在调用堆栈上有一个知道如何处理这种情况的处理程序。例如,如果您
    抛出{isHardStop:true,stopCode:SOME_code}
    并设计处理程序来检测这一点,那么您可能能够平展一些代码或选择更干净的语法

    此梯形图案例的处理程序的结构如下:

    try { ... } catch(thr) {
        if(!thr){
           // Is not Error or Json - Handle accordingly
        } else if(thr.isHardStop){
           // Handle the stop
        } else {
           // Most likely a real error. Handle accordingly
        }
    }
    

    尽管您可以抛出您想要的任何类型的数据,但在调试时这并不是最优的。JS
    Error
    对象包含有关错误和消息的所有信息。而字符串只能包含消息

    这些额外信息包括:

  • 文件名:从哪个文件引发错误
  • 行号:从哪一行抛出错误
  • stacktrace:从哪个函数调用错误
  • 以下是chrome devtools的stacktrace示例:


    虽然这是可能的,但它有意义吗?我宁愿捕获错误而不是字符串。相关:exports.login=(req,res)=>{login(req)。然后({token,user})=>{res.send(token);})。catch(err=>{if(typeof err=='string'){res status(401)。send(err);}else{console.log(err);res.status(500)。send(‘出了点问题’;}});}我确实是这样处理错误的,我也很困惑,我做得对吗?很抱歉没有把问题说清楚。我知道这些都是有效的,但我对直接使用字符串而不是使用错误对象的潜在问题感兴趣。啊,好吧,那就看看Ianzz的评论。它总结了所有的注意事项。但是我的建议是仍然是抛出带有自定义消息的
    错误
    对象。这样就省去了检查错误类型以将“您的”错误与其他本机生成的错误区分开来的麻烦…当然,除非您有意这样做(然后可能会在
    捕获
    范围中重新抛出
    错误
    对象)。值得注意的是,即使您抛出字符串,Chrome devtools也会打印堆栈跟踪。您将丢失
    .stack
    属性,该属性对于某些自动错误处理非常有用(例如,当设置自动向服务器报告错误以允许您调试生产中出现的错误时),但这更像是一种边缘情况;如果抛出字符串,则浏览器中的日常手动调试工作正常。例如,它可能会假定的
    .message
    属性是字符串,尝试对其调用string方法,然后分解。可以,但我不会说它“OK”。这是一个糟糕的想法,因为这意味着在没有堆栈跟踪的情况下调试bug要困难得多。@BenjaminGruenbaum如果你在Chrome中抛出一个字符串,你确实会得到一个堆栈跟踪。例如`function a(){throw“Hello World”}a();`将有如下堆栈跟踪:
    a@main.js:4(匿名)@main.js:7
    @Taurus谢谢,我不知道-现在尝试使用firefox中未连接的调试器执行此操作:)不,如果需要驱动程序流,请使用可以处理程序流的值返回/解析。例外是例外。如果您无法恢复并且需要系统抛出异常,那么这不是程序流,而是异常处理。我同意,除了异常处理之外,不应抛出错误和异常。然而,在我的示例中,我只是抛出一个对象,而不是实例化一个错误,因此它只是u