(JavaScript)自定义Error,扩展Error,深入继承,包装异常

自定义Error,扩展Error

扩展Error

Error类
// JavaScript 自身定义的内建的 Error 类的“伪代码”
class Error {
  constructor(message) {
    this.message = message;
    this.name = "Error"; // (不同的内建 error 类有不同的名字)
    this.stack = <call stack>; // 非标准的,但大多数环境都支持它
  }
}

继承Error
class ValidationError extends Error {
  constructor(message) {
    super(message); 
    this.name = "ValidationError"; 
  }
}

function test() {
  throw new ValidationError("Whoops!");
}

try {
  test();
} catch(err) {
  alert(err.message); // Whoops!
  alert(err.name); // ValidationError
  alert(err.stack); // 一个嵌套调用的列表,每个调用都有对应的行号
}

使用
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

// 用法
function readUser(json) {
  let user = JSON.parse(json);

  if (!user.age) {
    throw new ValidationError("No field: age");
  }
  if (!user.name) {
    throw new ValidationError("No field: name");
  }

  return user;
}

// try..catch 的工作示例

try {
  let user = readUser('{ "age": 25 }');
} catch (err) {
  /**
  *既处理我们的 ValidationError 又处理来自 JSON.parse的内建 SyntaxError。
  */
  if (err instanceof ValidationError) {
    alert("Invalid data: " + err.message); // Invalid data: No field: name
  } else if (err instanceof SyntaxError) { // (*)
    alert("JSON Syntax Error: " + err.message);
  } else {
    throw err; // 未知的 error,再次抛出 (**)
  }
}
  • err instanceof SyntaxError 也可以写成 err.name == "SyntaxError"
    但是使用 instanceof 更好。instanceof对新的继承类也适用

深入继承
  • 针对缺少属性的错误来制作一个更具体的 PropertyRequiredError 类。它将携带有关缺少的属性的相关信息。
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

class PropertyRequiredError extends ValidationError {
  constructor(property) {
    super("No property: " + property);
    this.name = "PropertyRequiredError";
    this.property = property;
  }
}

// 用法
function readUser(json) {
  let user = JSON.parse(json);

  if (!user.age) {
    throw new PropertyRequiredError("age");
  }
  if (!user.name) {
    throw new PropertyRequiredError("name");
  }

  return user;
}

// try..catch 的工作示例

try {
  let user = readUser('{ "age": 25 }');
} catch (err) {
  if (err instanceof ValidationError) {
    alert("Invalid data: " + err.message); // Invalid data: No property: name
    alert(err.name); // PropertyRequiredError
    alert(err.property); // name
  } else if (err instanceof SyntaxError) {
    alert("JSON Syntax Error: " + err.message);
  } else {
    throw err; // 为止 error,将其再次抛出
  }
}

简化代码:

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

class ValidationError extends MyError { }

class PropertyRequiredError extends ValidationError {
  constructor(property) {
    super("No property: " + property);
    this.property = property;
  }
}

// name 是对的
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError

包装异常

  • 我们将创建一个新的类 ReadError 来表示一般的“数据读取” error。
  • 函数readUser 将捕获内部发生的数据读取 error,例如 ValidationError 和 SyntaxError,并生成一个 ReadError 来进行替代。
  • 对象 ReadError 会把对原始 error 的引用保存在其 cause 属性中。
    之后,调用 readUser 的代码只需要检查 ReadError,而不必检查每种数据读取 error。并且,如果需要更多 error 细节,那么可以检查 readUser 的 cause 属性。
class ReadError extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = 'ReadError';
  }
}

class ValidationError extends Error { /*...*/ }
class PropertyRequiredError extends ValidationError { /* ... */ }

function validateUser(user) {
  if (!user.age) {
    throw new PropertyRequiredError("age");
  }

  if (!user.name) {
    throw new PropertyRequiredError("name");
  }
}

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

}

try {
  readUser('{bad json}');
} catch (e) {
  if (e instanceof ReadError) {
    alert(e);
    // Original error: SyntaxError: Unexpected token b in JSON at position 1
    alert("Original error: " + e.cause);
  } else {
    throw e;
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
async-validator 是一个用于前端表单验证的库,它支持自定义错误信息。可以通过配置 `messages` 对象来修改默认错误信息,也可以通过 `rules` 对象添加自定义规则和错误信息。 如果想要自定义错误信息的显示样式,可以通过 `validate` 方法的第二个参数传入一个 `options` 对象,在 `options` 对象配置 `error` 函数,该函数会在验证不通过时被调用,可以在该函数自定义错误信息的显示方式。 例如: ```javascript const validator = require('async-validator'); const descriptor = { name: { type: 'string', required: true, message: '请输入姓名' }, age: { type: 'number', required: true, message: '请输入年龄' } }; const options = { async error (errors) { const errorText = errors.map(error => error.message).join('<br>'); const errorContainer = document.getElementById('error-container'); errorContainer.innerHTML = errorText; } }; const validateForm = async (formData) => { const validate = new validator(descriptor); try { await validate.validate(formData, options); console.log('验证通过'); } catch (errors) { console.error(errors); } }; validateForm({ name: '', age: '' }); ``` 在上面的例子,我们配置了一个 `error` 函数来自定义错误信息的显示方式,在该函数,我们将所有错误信息拼接成一个字符串,并显示在 `id` 为 `error-container` 的元素,你可以根据实际情况来修改这个函数。 希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值