Custom Validators中Promise.reject()与throw new Error()的使用区别
结论先行
你给出的两个示例在执行效果上完全等价:Promise.then 回调内同步抛出的 Error 会自动被外层 Promise 包装为 rejected 状态返回,express-validator 底层拿到的校验结果没有任何差异。
二者的核心区别与适用场景
- 必须使用
Promise.reject()的场景:
当你的错误抛出逻辑不在 Promise 链的同步回调内时(比如老式回调 API、setTimeout等非 Promise 异步回调),throw出来的错误无法被外层 Promise 捕获,只会导致进程抛出未捕获异常,这时候必须通过Promise.reject()主动返回拒绝状态。
示例:body('phone').custom(value => { return new Promise((resolve, reject) => { // 基于回调的老式接口 legacyCheckPhoneExist(value, (err, isExist) => { if (err) return reject('手机号校验失败') if (isExist) return reject('手机号已注册') resolve() }) }) }) - 二者都可用的场景差异:
仅语义层面有区别:throw new Error()更偏向同步逻辑的异常抛出写法,Promise.reject()更明确表达这是异步校验流程的预期错误返回。
选型建议
二者都可用的场景下没有强制优劣,按团队编码规范和个人习惯选择即可:
- 如果使用
async/await写法写自定义校验,throw new Error()写法更自然简洁,是大部分人的首选:body('email').custom(async value => { const user = await User.findUserByEmail(value) if (user) throw new Error('E-mail already in use') }) - 如果想要明确区分「校验不通过的预期错误」和「代码运行异常」,可以优先选
Promise.reject(),语义更清晰。 - 注意无论选哪种写法,都建议传递
Error对象而非纯字符串,方便后续排查问题时能拿到错误堆栈信息。
内容的提问来源于stack exchange,提问作者Valachio
相关产品推荐
相关产品推荐

