阅读笔记 - 异常处理及扩展

06/18 10:32

 

相关文章


【第1641期】异常处理,"try..catch"
【第1643期】自定义错误及扩展错误

笔记梳理


使用

以 JSON.parse 方法为例

let json = '{ "age": 30 }'; // 不完整的数据

try {
  let user = JSON.parse(json); // <-- 没有异常
  if (!user.name) {
    throw new SyntaxError("Incomplete data: no name"); // (*)
  }
  alert( user.name );
} catch(e) {
  alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name
} finally {
  alert( 'finally' );
}

原则及细节

1. try...catch

try...catch 只能处理有效代码之中的异常。这类异常被称为 “runtime errors”。

如果一个异常是发生在计划中将要执行的代码中,例如在 setTimeout 中,那么 try...catch 不能捕捉到。因为函数本身要稍后才能执行,这时引擎已经离开了 try..catch 结构。

2. rethrowing

当异常不想在这层处理时,抛出给外层处理

3. 自定义异常

继承自内置的 Error 类,方便使用 instanceof 检测 Error 类型

自定义基础异常类:直接使用构造器的名称作为异常的名称,这样就不用每自定义一个异常类型,都要定义一次名称

class MyError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
  }
}

包装高级别异常:将低等级异常细节包装在高级别异常的属性中,这样外层代码只需处理高级别异常,无需分别处理低级别异常

// ReadError 异常类
class ReadError extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = 'ReadError';
  }
}

// 使用 ReadError 抛出异常
function readUser(json) {
  let user;

  try {
    user = JSON.parse(json);
  } catch (err) {
    if (err instanceof SyntaxError) {
      throw new ReadError("Syntax Error", err);
    } else {
      throw err;
    }
  }

  try {
    validateUser(user);
  } catch (err) {
    if (err instanceof ValidationError) {
      throw new ReadError("Validation Error", err);
    } else {
      throw err;
    }
  }
}

// 外层处理 ReadError
try {
  readUser('{bad json}');
} catch (e) {
  if (e instanceof ReadError) {
    alert(e);
    // 原错误:语法错误:在位置 1 处不应有 b
    alert("Original error: " + e.cause);
  } else {
    throw e;
  }
}

 

业务思考


  1. 业务中注意一些可能会导致异常的代码用 try...catch 包裹,使代码健壮性更好+易于调试
  2. 业务中使用全局 catch,主要目的是方便调试
  3. 扩展异常时注意继承,方便根据异常类型判断

 

思维导图


阅读笔记 - 异常处理及扩展_第1张图片

 

你可能感兴趣的:(前端)