在 async/await 中自定义错误需继承 Error 类并用 throw 抛出实例,确保堆栈、instanceof 判断正常;调用处用 try/catch 捕获,按 error.name 或 instanceof 区分类型做差异化处理。
在 async/await 环境下自定义错误抛出,核心是用 throw 抛出一个继承自 Error 的实例(或至少具备 message 和 name 属性的对象),并在调用处用 try/catch 捕获处理。
推荐继承原生 Error 类,确保堆栈信息、instanceof 判断和调试体验正常:
super(message),并设置 this.name
code、status)用于业务区分class ValidationError extends Error { constructor(message, field) { super(message); this.name = 'ValidationError'; this.code = 'VALIDATION_ERROR'; this.field = field; }}// 使用async function createUser(data) { if (!data.email) { throw new ValidationError('邮箱不能为空', 'email'); } // ...}
async 函数本身不会自动将 rejected Promise 转为自定义错误;需显式判断响应或结果,再决定是否抛出:
response.status 或返回体中的 error 字段catch 原始错误,而是根据业务逻辑“翻译”成领域错误throw err(可能丢失上下文),建议包装后再抛async function fetchUser(id) { const res = await fetch(`/api/users/${id}`); const data = await res.json(); if (!res.ok) { throw new ApiError(`请求失败: ${data.message || res.statusText}`, { status: res.status, code: data.code }); } if (!data.user) { throw new NotFoundError('用户不存在'); } return data.user;}
在大型项目中,可在请求函数或业务方法外层做标准化错误转换:
safeAwait 工具函数,自动将 Promise rejection 映射为自定义错误NetworkError、AuthError 等await 都写重复的 if (res?.error) 判断try/catch 包裹单个 await 更清晰,不建议把多个 await 塞进一个 try 块里——否则无法准确定位哪一步出错。利用 instanceof 或 error.name 区分错误类型,实现差异化处理:
ValidationError 提示表单字段问题AuthError 触发登出或跳转登录页try { await submitForm(data);} catch (err) { if (err instanceof ValidationError) { showFieldError(err.field, err.message); } else if (err instanceof AuthError) { redirectToLogin(); } else { notifyUser('操作失败,请稍后重试'); reportError(err); }}