Skip to content

异常处理 Exception

模块位于 src/core/Exception。路由内抛错会进入 handleException:先匹配自定义 Advice,再回落内置映射,统一输出 ResponseData

全局 Advice(推荐)

把处理类放在 src/business/advice/Application.start() 会自动扫描加载(顺序:entity → mapper → service → controller → advice)。

仓库已有:business/advice/GlobalExceptionHandler.ts

ts
import {
  ControllerAdvice,
  ExceptionHandler,
  BizException,
} from '@/core/Application'
import { ValidationError } from '@/core/Validate'
import { AuthError } from '@/core/Auth'
import { OrmError } from '@/core/ORM'
import { GuardError } from '@/core/RateLimit'

@ControllerAdvice()
export default class GlobalExceptionHandler {
  @ExceptionHandler(ValidationError)
  handleValidation(error: ValidationError) {
    return { message: error.message, code: error.code, data: error.errors }
  }

  @ExceptionHandler(BizException)
  handleBiz(error: BizException) {
    return {
      message: error.message,
      code: error.code,
      data: error.data,
      httpStatus: error.httpStatus,
    }
  }

  @ExceptionHandler(AuthError)
  handleAuth(error: AuthError) {
    return { message: error.message, code: error.code }
  }

  @ExceptionHandler(OrmError)
  handleOrm(error: OrmError) {
    return { message: error.message, code: error.code }
  }

  @ExceptionHandler(GuardError)
  handleGuard(error: GuardError) {
    return { message: error.message, code: error.code }
  }

  @ExceptionHandler(Error) // 兜底
  handleError(error: Error) {
    return {
      message: error.message || '服务器内部错误',
      code: 500,
      httpStatus: 500,
    }
  }
}

匹配顺序:精确类型 → 最近父类 → @ExceptionHandler(Error) 兜底。同类型后注册优先。

处理器返回值

返回行为
ResponseData 形态对象直接 send,HTTP 默认 200
{ message, code?, data?, httpStatus? }组装 ResponseData.error
{ rawBody, httpStatus? }原样发送
null / undefined回落内置映射

业务抛错

ts
import { BizException } from '@/core/Application'

throw new BizException('库存不足')
// 可选:message, code, data, httpStatus
throw new BizException('未授权', 401, null, 200)

也可继续抛 OrmError / AuthError / ValidationError 等,由 Advice 统一处理。

编程式注册

ts
import { registerHandler, Exception } from '@/core/Exception'

registerHandler(SomeError, (error) => ({
  message: error.message,
  code: 500,
}))

// Application.registry(Exception()) 仅为占位,可不写

内置回落(无 Advice 或返回空时)

异常典型 HTTP / code
BizExceptionhttpStatus + 业务 code
ValidationError200 + 400data 为字段错误
AuthError / OrmError / GuardError200 + 各自 code
其它HTTP 500

相关章节

基于 VitePress 构建