关于try/catch的使用实践疑问

码码码畜
  • 2.9k

个人看到的网上各种代码里面,try/catch代码99%都是在catch中打印一下错误信息,好像就没有其它用途了,太让人困惑了,有没有try/catch的其它的最佳实践或者书籍,谢谢了!

回复
阅读 1.8k
5 个回答

对于前端而言,大部分的问题都是由于代码本身不够健壮或者干脆就写的有问题,所以 try/catch 仅仅用于输出错误以便定位问题。如果仅仅是部分用户终端出现问题、自身又无法定位问题,可能还会辅以错误日志上报等行为。这种情况,我们称之为异常exception)。

但有一些情况下是错误error)而非异常,需要一些“体面”的处理,下面举几个具体的例子。


场景一:依赖 JS 本身的特性做某些处理。

比如尝试校验一个字符串是否是 JSON 格式,可以:

try {
    return JSON.parse(data);
    // 是一个 JSON
} catch (err) {
    // 不是有效的 JSON 字符串
    return null;
}

再比如检查当前版本的浏览器是否支持某些 API:

try { 
    return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0; 
    // 支持 webp 图片
} catch (err) { 
    return false;
    // 不支持 webp 图片
}

这里的 try/catch 实际形成了 if/else 的逻辑,并不是为了捕捉异常。


场景二:async/await 下的错误捕捉:

try {
    await $ajax(url, data);
} catch (err) {
    alert('加载失败:' + err);
}

因为业务逻辑依赖了一个外部接口,而这个接口已经脱离的前端能控制的范围,你无法保证其一定没错误,所以这里的 try/catch 一般用于错误信息的友好展示。当然,对于有异常情况上报等需要的场景,这里也可以再做一次日志。

异常处理啊,避免错误直接到达视图层,服务端捕捉到异常先优雅的处理。还有类似try-with-resource对资源进行自动管理,编码比较优雅

代码运行到catch说明程序运行出错已经不符合我们设计的预期了,我们只是捕获了它避免系统崩溃,你在dev阶段从控制台看到错误就该从代码层面找到原因避免错误再次出现。
当然有些不可抗力,譬如网络问题,服务端错误等,就给用户提示,有必要的话储存错误信息通知开发者,catch并不是拿来用的,大部分情景下它是让我们迅速知道哪个地方出问题了并去解决它。

  1. 没看到过类似的书籍
  2. try/catch 的处理逻辑和业务高度相关。
  3. 举个例子,GitHub desktop 里有个更新功能,需要用到网络,出错概率很高,就要用 try/catch。如果是后台自动更新,catch 到错误之后,直接忽略,然后过一段时间重试就好;如果是用户手动点的更新,就要原原本本把错误告知用户。
  4. 所以我觉得不太可能会有“教最佳实践的书”,只能我们开发的时候以逻辑推断和实现

try...catch...finally 只是一种中断式的错误处理方式。try 语句块中如果发生错误,就会在 catch 块中去尝试处理,而不管是对是错,都会去处理 finally 块。

如果用原来 C 风格的错误处理来写,就像这样

function process() {
  if (error) {
     return errorObject;
  }
  
  return null; // 这句可省,反正不写就是返回 undefined
}

(() => {
  const err = process();
  if (err) {
     console.log("Error", err);
  }
})();

你看,这个如果用 try ... catch ... 的方式是写成这样

function process() {
  if (error) {
     throw errorObject;
  }
}

(() => {
  try {
     process();
  } catch (err) {
     console.log("Error", err);
  }
})();

所以,其实不管你用哪种方式来写,关键在于处理逻辑,如果发生错误应该如何处理。形式都是次要的。

顺便提一下,不管是 catch 块还是 finally 块中的代码,都有可能再次引发错误,那么也需要进行错误处理,所以就会出现在 catchfinally 块嵌 try ... catch ... 的情况……你看,是不是跟多层 if 分支长得差不多

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏