Express(NodeJS/TypeScript)如何在响应中返回函数结果与校验错误
问题原因
当前逻辑无法透传校验错误的核心原因有两点:
- 执行顺序错误:先执行了数据库
save操作再做数据校验,即使校验发现错误,脏数据已经写入数据库 - 返回值作用域错误:你在
validate().then()的回调函数内return errors,这个返回值只在当前回调函数内生效,外层create方法接收不到这个返回值,永远会返回后续的createCompany对象,接口层自然拿不到校验错误信息。
修正代码
1. 修改Repository层(SqlCompanyRepository.ts)
把校验逻辑前置到存库操作前,校验不通过直接抛出错误,阻断后续逻辑:
async create(company: CompanyCommand): Promise<CompanyEntity> { // 先执行数据校验 const errors = await validate(company); if (errors.length > 0) { // 抛出带状态码、错误信息的自定义错误 throw { statusCode: 400, errors: errors }; } // 校验通过后再执行数据库写入 return await dataSource.getRepository(CompanyEntity).save(company); }
2. 修改路由层(index.ts)
增加异步错误捕获逻辑,接住Repository层抛出的校验错误,返回给客户端:
app.post("/company", async (req, res) => { try { const company = new CompanyCommand() company.id = crypto.randomUUID() company.name = req.body.name company.email = req.body.email company.password = req.body.password const checkEmail = await companyRepository.findByEmail(company.email) if (!!checkEmail) { return res.status(409).send("Email already exists.") } const companyResult = await companyRepository.create(company) return res.status(201).send(companyResult) } catch (err) { // 识别校验类错误,返回400状态和错误详情 if (err.statusCode === 400) { return res.status(400).send({ message: "Request params validation failed", validationErrors: err.errors }) } // 其他未知错误统一返回500服务端错误 return res.status(500).send("Internal server error") } })
注意事项
- 所有Express异步路由处理逻辑必须包裹
try/catch,否则未捕获的抛出错误会导致服务进程异常 - 数据校验、权限校验类逻辑必须放在数据库写操作之前执行,避免无效脏数据落库
- Promise回调内的return无法被外层作用域接收,要终止逻辑向外传递错误时,直接使用
throw抛出即可
内容的提问来源于stack exchange,提问作者corsema
相关产品推荐
相关产品推荐

