捕获语句无法捕获抛出的错误

80
由于某种原因,这段代码给我抛出了一个未捕获的异常错误。看起来catch块没有捕获该错误。在try catch块中定义的变量作用域是否包括嵌套函数中的错误,以及在上层的catch语句中期望捕获该错误?我在处理的应用程序中去除了一些敏感数据,但预计leadInfo [0 / 1]将是一个32个字符的字母数字字符串,我从URL参数中提取它。
这里的根本问题是我的AJAX调用从API返回一个错误,而该错误在应用程序中未被正确处理。因此需要使用throw语句。AJAX调用正常完成,并返回不包含电子邮件地址属性的JSON对象,因此我需要以某种方式处理它,以更改页面以反映该内容。
    jQuery(document).ready(function(){
        try {
            url = "http://api.com/api/v1/lead/" + leadInfo[1]

            jQuery.ajax({
                type: 'GET',
                contentType: 'application/json',
                url: url,
                dataType : 'jsonp',
                success: function (result) {

                    result = jQuery.parseJSON(result);

                    if(!result.data.email){
                        throw ('New exception');
                    }
                    console.log(result);
                    jQuery('.email').html(result.data.email);
                }
            });


            jQuery('.surveryButton').click(function(){
                window.location.replace("http://" + pgInventory.host + pgInventory.path + leadInfo[0] + "&curLeadId=" + leadInfo[1] + "&curViewedPages=0");
            });
        }
        catch(err) {
            jQuery('.email').html('your e-mail address');
            jQuery('#arrowContent').remove();
        }
});

你在 catch 块中也可能会抛出另一个错误吗?我发现这就是我当时的问题所在。 - CDM social medias in bio
3个回答

142
您的 try catch 代码块失败的原因是 AJAX 请求是异步的。 在发送请求本身时,try catch 代码块将在 AJAX 调用之前执行,但在返回结果时(即迟些时候)抛出错误。
当执行 try catch 代码块时,没有错误。 当错误被抛出时,就没有 try catch 了。 如果您需要针对 AJAX 请求使用 try catch,请始终将 ajax try catch 代码块放置在 success 回调函数内部,永远不要将其放在外部。
以下是正确的做法:
success: function (result) {
    try {
      result = jQuery.parseJSON(result);

      if (!result.data.email) {
         throw ('New exception');
      }
      console.log(result);
      jQuery('.email').html(result.data.email);
    } catch (exception) {
      console.error("bla");
    };
}

1
看起来我对JSONP调用的理解有些颠倒了。我一直以为JSONP调用总是被强制同步,结果事实正好相反,它们总是被强制异步。现在这一点信息已经得到澄清,这完全说得通了。感谢您的快速回复! - Xenology
1
请注意,等待抛出错误的 Promise 将像预期的那样将错误冒泡。 - diggity
谢谢老兄,我会记得在异步函数中无法抛出错误这一点的。 - Jenuel Ganawed

7
由于javascript中回调方法的异步性质,抛出错误的函数上下文与原始上下文不同。您应该采取以下方式:
success: function (result) {
  try {
    result = jQuery.parseJSON(result);
    if(!result.data.email){
      throw ('New exception');
    }
    console.log(result);
    jQuery('.email').html(result.data.email);
  }
  catch(err) {
    // Dealing with the error
  }
}

我建议您查看这篇关于Javascript中非常特殊的上下文闭包绑定的优秀文章


1
问题在于ajax默认是异步的。你的异常并不是从$.ajax函数中抛出的,而是在成功时触发回调函数(稍后触发)中抛出的。
你应该添加一个error: function(data) {}参数来处理服务器响应错误,并且你应该将try/catch块放在回调函数内部。
如果你真的想在回调外捕获它,那么你应该考虑调用一个函数而不是抛出一个异常,因为我不知道怎么做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接