欢迎光临
我们一直在努力

异常与统一封装架构:规范统一返回值、全局异常与参数校验

文章目录

    • 📌 技术名片
      • 💡 一句话理解
    • 一、反面教材:AI 的“自由发挥”
      • 问题 1:返回格式不统一
      • 问题 2:参数校验散落在业务代码里
      • 问题 3:异常处理方式不一致
      • 问题 4:系统内部错误直接暴露给用户
      • 问题 5:每个接口都在重复造轮子
    • 二、架构规则:人类先把“设计图纸”画好
      • 规则 1:所有普通 API 使用统一返回结构
      • 规则 2:API 不要到处自己拼 JSON
      • 规则 3:输入格式由 Schema 和 Validator 负责
      • 规则 4:复杂字段使用 Validator
      • 规则 5:业务错误使用统一异常类型
      • 规则 6:异常集中到全局处理
    • 三、这样做有什么好处?
      • 1. AI 不再随意创造返回结构
      • 2. 前端调用变得非常简单
      • 3. 校验规则不会散落
      • 4. Service 更干净
      • 5. AI 更容易理解“什么错误属于哪里”
    • 四、AI 最容易出现的“失控现场”
    • 五、提示词落地:把规则教给 AI
    • 六、正面产出:miniagent 是怎么做的?
      • 1. 统一返回值:ApiResponse
      • 2. 分页结果也统一封装
      • 3. 业务异常也有统一基类
      • 4. 错误信息还统一接入 I18n
      • 七、全局异常:异常只需要“抛”,不用到处“接”
      • 未知异常也统一兜底
    • 八、Validator:错误输入尽量不要进入业务层
      • 密码校验进一步复用 Validator
        • Annotated
        • AfterValidator
    • 九、最终形成了一条非常清晰的请求链
    • 十、架构赋能后的 AI 会怎么写?
    • 结语
    • 开源代码

AI 很擅长快速写接口,比如你告诉它:

“增加一个创建用户接口。”

它很可能几分钟就能给出一段能运行的代码,但如果项目里没有统一规范,不同接口很快就会变成这样:

{
"success": true
}

另一个接口返回:

{
"code": 0,
"msg": "ok",
"result": {}
}

再一个接口出错时直接返回:

{
"error": "user not found"
}

甚至有些地方直接把数据库异常抛给前端。

单个接口都“能跑”,整个系统却越来越难维护。

所以,AI 编程里有一类非常重要、却经常被忽略的基础架构:

统一返回值 + 全局异常处理 + 统一参数校验。

它们的作用,就是提前规定:

成功怎么返回,失败怎么返回,非法输入在哪里拦截。


📌 技术名片

统一异常与接口封装架构

指通过统一响应模型、统一异常体系和统一入参校验机制,让整个系统的接口具有一致的输入、输出和错误处理方式。

这里常见三个核心概念:

  • API Response Envelope:接口响应封装,即规定所有接口统一返回什么结构;
  • Global Exception Handling:全局异常处理,即异常集中处理,而不是每个接口各写一遍;
  • Validator:校验器,用于在数据进入业务逻辑之前检查格式、范围和合法性。

💡 一句话理解

可以把 API 想象成机场安检。

旅客进入机场以后:

检查证件

检查行李

符合规则

进入候机区

如果有问题:

证件错误
行李违规
身份异常

不会让每一个登机口自己决定:

“这个人该怎么办?”

而是由统一的安检规则处理。

软件系统也一样:

用户请求

参数校验

业务处理

统一返回

发生异常时:

业务异常
系统异常

统一异常处理

标准错误响应

这对 AI 尤其重要。因为如果没有规则,AI 很容易:

每写一个接口,就重新发明一次返回格式和错误处理方式。


一、反面教材:AI 的“自由发挥”

假设让 AI 实现一个创建用户接口:

用户名至少 3 个字符,密码必须符合安全规则。如果用户名已经存在,要给出错误提示。

没有架构约束时,AI 很可能写成:

@router.post("/users")
async def create_user(data: dict):
if len(data["username"]) < 3:
return {
"success": False,
"message": "username too short"
}

if len(data["password"]) < 8:
return {
"code": 400,
"error": "invalid password"
}

user = await db.get_user(data["username"])

if user:
raise HTTPException(
status_code=400,
detail="user already exists"
)

try:
new_user = await db.create_user(data)

return {
"result": new_user,
"status": "ok"
}

except Exception as e:
return {
"error": str(e)
}

功能似乎完整。

但里面已经出现了很多问题。


问题 1:返回格式不统一

同一个接口里甚至出现了:

{
"success": false
}

和:

{
"code": 400
}

以及:

{
"status": "ok"
}

前端每调用一个接口,都要重新猜:

这次到底应该判断 success、code 还是 status?


问题 2:参数校验散落在业务代码里

if len(data["username"]) < 3:

if len(data["password"]) < 8:

这些本质上属于:

输入是否合法?

却混进了业务逻辑。

下一个 AI 再写一个“修改用户”接口,很可能又复制一遍。


问题 3:异常处理方式不一致

用户名存在:

raise HTTPException(...)

密码错误:

return {...}

数据库异常:

except Exception as e:
return {"error": str(e)}

三种错误,三套处理方式。


问题 4:系统内部错误直接暴露给用户

str(e)

可能把:

数据库表名
SQL 语句
服务器路径
内部配置

直接返回前端。

这不仅难看,还可能带来安全风险。


问题 5:每个接口都在重复造轮子

当系统有 100 个接口以后,就可能出现:

100 套参数判断
100 套 try / except
20 种返回结构
10 种错误格式

真正的问题不是 AI 不会写代码。

而是:

没有统一规范时,AI 会非常高效地制造不一致。


二、架构规则:人类先把“设计图纸”画好

解决这个问题,可以把整个请求过程标准化:

客户端请求

Schema / Validator
入参校验

API

Service

业务异常

Global Exception Handler
全局异常处理

ApiResponse
统一返回

然后给 AI 明确几条规则。


规则 1:所有普通 API 使用统一返回结构

例如统一规定:

{
"code": 200,
"message": "success",
"data": {}
}

三个字段各司其职:

code
业务 / 状态代码

message
给人看的提示信息

data
真正返回的数据

成功时:

{
"code": 200,
"message": "success",
"data": {
"id": 12,
"username": "tom"
}
}

失败时:

{
"code": 404,
"message": "User '12' not found"
}

前端不用再猜。


规则 2:API 不要到处自己拼 JSON

不要:

return {
"success": True,
"result": data
}

也不要:

return {
"status": "ok",
"payload": data
}

统一使用:

return ApiResponse(data=data)

这样返回格式只有一份定义。


规则 3:输入格式由 Schema 和 Validator 负责

例如:

class UserCreate(BaseModel):
username: str = Field(
...,
min_length=3,
max_length=100
)

这里的 Field 可以理解为:

字段规则。

它直接规定:

username
最少 3 个字符
最多 100 个字符

AI 不需要在每一个 API 里重新写:

if len(username) < 3:


规则 4:复杂字段使用 Validator

有些校验不是简单长度就能完成。

例如密码可能要求:

至少多少位
包含大小写字母
包含数字
包含特殊字符

这时候就适合使用:

Validator(校验器)

把密码规则集中在一个地方。

以后:

创建用户
重置密码
修改密码

全部复用。


规则 5:业务错误使用统一异常类型

例如:

用户不存在
Agent 不存在
知识库不存在

它们都属于:

Not Found(资源不存在)

可以统一使用:

NotFoundError

而:

用户名已存在
Agent 名称重复

可以统一归入:

AlreadyExistsError

这样 Service 只需要表达:

“发生了什么业务错误。”

不用关心 HTTP 最终应该返回 404、409 还是其他状态码。


规则 6:异常集中到全局处理

业务代码可以:

raise NotFoundError(...)

全局异常处理器负责:

NotFoundError

HTTP 404

ApiResponse

而不是每一个接口:

try:
...
except:
...

重复几十遍。


三、这样做有什么好处?

对于传统开发,这叫工程规范。对于 AI 编程,它还有更直接的价值。


1. AI 不再随意创造返回结构

项目里只有:

ApiResponse

这一套规则。

AI 看到现有代码以后,更容易继续写:

return ApiResponse(data=result)


2. 前端调用变得非常简单

前端可以统一认为:

code
message
data

永远存在。

于是统一 HTTP Client 就可以统一处理:

成功
错误
Token 失效
提示信息

不用每个页面单独适配。


3. 校验规则不会散落

例如密码规则如果修改:

最低 8 位改成最低 12 位。

如果规则集中在 Validator,只改一个地方即可。

如果散落在:

注册
创建用户
修改密码
重置密码
管理员后台

五个接口中,就很容易漏改。


4. Service 更干净

业务代码不需要反复:

try:
...
except HTTPException:
...

它只处理业务:

用户不存在

抛 NotFoundError

用户已存在

抛 AlreadyExistsError

错误怎样转换成 HTTP,由外层统一完成。


5. AI 更容易理解“什么错误属于哪里”

可以建立非常清楚的边界:

输入格式错误
→ Validator

业务规则错误
→ Domain Error

系统未知错误
→ Global Exception Handler

响应格式
→ ApiResponse

这相当于把错误处理也进行了分层。


四、AI 最容易出现的“失控现场”

一个非常典型的失控过程是:

第一次 AI 写:

return {"success": True}

第二次看到另一个项目习惯,于是写:

return {
"code": 0,
"message": "ok"
}

第三次又直接:

raise HTTPException(...)

第四次为了“保险”:

try:
...
except Exception:
...

最后系统里可能出现:

API A → HTTPException
API B → 自定义 JSON
API C → ApiResponse
API D → try / except
API E → 返回 None

而 AI 有一个非常现实的特点:

它经常会模仿项目里已经存在的代码。

项目里如果同时存在五种写法,后续 AI 就很难知道:

哪一种才是真正的标准?

所以统一异常架构还有一个非常重要的价值:

给 AI 提供大量一致的正确范例。


五、提示词落地:把规则教给 AI

仅仅告诉 AI:

“注意异常处理。”

几乎没有实际作用。

更有效的是写成具体工程规则。

例如可以加入项目级规则:

## API 响应和验证规则

所有标准的 JSON API 必须使用项目统一的

ApiResponse 响应信封。

标准响应字段:
– code
– message
– data

规则:
– 除非现有协议明确要求,否则请勿创建其他响应结构,例如:success/result/payload/status。
– API 路由应返回 ApiResponse,而不是手动构建响应字典。
– 请求负载必须使用现有的 Pydantic schema。
– 简单的输入约束(例如 length、range 和 required 字段)应在 Pydantic 字段定义中声明。
– 可重用或复杂的验证规则应使用项目现有的验证器。
– 请勿在 API 路由中重复验证逻辑。
– 业务错误必须使用项目的域异常类型,例如:NotFoundError 和 AlreadyExistsError。
– 请勿在服务中将业务错误转换为 HTTPException。
– 不要为每个 API 路由添加重复的 try/except 代码块。
– 让全局异常处理机制将已知的异常转换为标准化的 API 响应。
– 意外的内部异常不得在生产环境中暴露敏感的实现细节。

以后让 AI 开发接口时,可以进一步提示:

实现“创建用户”接口。

请严格遵守项目现有的统一接口规范:

1. 请求参数使用已有 Pydantic Schema;
2. 字段长度、范围等规则放在 Schema / Validator;
3. API 返回统一使用 ApiResponse;
4. 用户已存在等业务错误使用现有 Domain Error;
5. 不要在 Router 中重复编写 try/except;
6. 不要自行创建新的错误返回格式;
7. 优先复用项目已有 Validator 和异常类型。

实现前先检查:
app/schemas/common.py
相关业务 Schema
现有 Service
全局异常处理代码。

这时候 AI 不再是在“自由设计一个接口”,而是在:

现有异常与响应协议下增加一个接口。


六、正面产出:miniagent 是怎么做的?

miniagent 已经把:

统一响应
业务异常
全局异常处理
Pydantic 参数校验

几个部分组合起来了,参见下图:

#mermaid-svg-wuZtSVwramHbZviH{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wuZtSVwramHbZviH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wuZtSVwramHbZviH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wuZtSVwramHbZviH .error-icon{fill:#552222;}#mermaid-svg-wuZtSVwramHbZviH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wuZtSVwramHbZviH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wuZtSVwramHbZviH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wuZtSVwramHbZviH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wuZtSVwramHbZviH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wuZtSVwramHbZviH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wuZtSVwramHbZviH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wuZtSVwramHbZviH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wuZtSVwramHbZviH .marker.cross{stroke:#333333;}#mermaid-svg-wuZtSVwramHbZviH svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wuZtSVwramHbZviH p{margin:0;}#mermaid-svg-wuZtSVwramHbZviH .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-wuZtSVwramHbZviH .cluster-label text{fill:#333;}#mermaid-svg-wuZtSVwramHbZviH .cluster-label span{color:#333;}#mermaid-svg-wuZtSVwramHbZviH .cluster-label span p{background-color:transparent;}#mermaid-svg-wuZtSVwramHbZviH .label text,#mermaid-svg-wuZtSVwramHbZviH span{fill:#333;color:#333;}#mermaid-svg-wuZtSVwramHbZviH .node rect,#mermaid-svg-wuZtSVwramHbZviH .node circle,#mermaid-svg-wuZtSVwramHbZviH .node ellipse,#mermaid-svg-wuZtSVwramHbZviH .node polygon,#mermaid-svg-wuZtSVwramHbZviH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wuZtSVwramHbZviH .rough-node .label text,#mermaid-svg-wuZtSVwramHbZviH .node .label text,#mermaid-svg-wuZtSVwramHbZviH .image-shape .label,#mermaid-svg-wuZtSVwramHbZviH .icon-shape .label{text-anchor:middle;}#mermaid-svg-wuZtSVwramHbZviH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wuZtSVwramHbZviH .rough-node .label,#mermaid-svg-wuZtSVwramHbZviH .node .label,#mermaid-svg-wuZtSVwramHbZviH .image-shape .label,#mermaid-svg-wuZtSVwramHbZviH .icon-shape .label{text-align:center;}#mermaid-svg-wuZtSVwramHbZviH .node.clickable{cursor:pointer;}#mermaid-svg-wuZtSVwramHbZviH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wuZtSVwramHbZviH .arrowheadPath{fill:#333333;}#mermaid-svg-wuZtSVwramHbZviH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wuZtSVwramHbZviH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wuZtSVwramHbZviH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wuZtSVwramHbZviH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wuZtSVwramHbZviH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wuZtSVwramHbZviH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wuZtSVwramHbZviH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wuZtSVwramHbZviH .cluster text{fill:#333;}#mermaid-svg-wuZtSVwramHbZviH .cluster span{color:#333;}#mermaid-svg-wuZtSVwramHbZviH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wuZtSVwramHbZviH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wuZtSVwramHbZviH rect.text{fill:none;stroke-width:0;}#mermaid-svg-wuZtSVwramHbZviH .icon-shape,#mermaid-svg-wuZtSVwramHbZviH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wuZtSVwramHbZviH .icon-shape p,#mermaid-svg-wuZtSVwramHbZviH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wuZtSVwramHbZviH .icon-shape .label rect,#mermaid-svg-wuZtSVwramHbZviH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wuZtSVwramHbZviH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wuZtSVwramHbZviH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wuZtSVwramHbZviH :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

Python ExceptionPython 异常基类

BaseDomainError业务异常基类

NotFoundError资源不存在

AlreadyExistsError资源已存在

EmptyDataError数据为空

BadRequestError错误请求

ReadOnlyError资源只读

InvalidValueError值不合法

Global Exception Handler全局异常处理

ApiResponse统一返回格式code · message · data


1. 统一返回值:ApiResponse

miniagent 在 backend/app/schemas/common.py 定义了统一顶层响应模型:

class ApiResponse(BaseModel, Generic[T]):
"""
Generic top-level API response envelope.
"""

code: int = Field(
200,
description="Business status code, 200 = success"
)

message: str = Field(
"success",
description="Human-readable status message"
)

data: Optional[T] = Field(
None,
description="Response payload"
)

也就是说,普通接口统一围绕:

{
"code": 200,
"message": "success",
"data": {}
}

展开。

这里还使用了:

Generic[T]

Generic 的意思是泛型。

可以简单理解成:

data 可以装不同类型的数据,但外面的 code / message / data 外壳保持不变。

例如:

ApiResponse[UserOut]
ApiResponse[AgentOut]
ApiResponse[PageResult]

内部数据不同,外层协议统一。


2. 分页结果也统一封装

同一个文件里还定义了:

class PageResult(BaseModel, Generic[T]):
total: int
page: int
page_size: int
data: List[T]

因此分页接口不需要今天返回:

rows
count
current

明天又变成:

items
total
pageNum

而是统一:

{
"total": 100,
"page": 1,
"page_size": 20,
"data": []
}

这对 AI 特别重要,因为 AI 新增分页接口时,可以直接复用现有结构。


3. 业务异常也有统一基类

miniagent 定义:

class BaseDomainError(Exception):
"""
Business Logic Exception Base Class
"""

即:

领域业务异常基类。

然后继续派生:

class NotFoundError(BaseDomainError):
...

class AlreadyExistsError(BaseDomainError):
...

class EmptyDataError(BaseDomainError):
...

class ReadOnlyError(BaseDomainError):
...

class InvalidValueError(BaseDomainError):
...

这样业务代码遇到错误时,可以不需要重新创造:

UserNotExistException
MissingAgentException
KBNotFoundException
NoDocumentException

各种完全不同的错误体系,而是尽量归入现有语义。


4. 错误信息还统一接入 I18n

这里的 I18n 是:

Internationalization,国际化。

BaseDomainError 可以通过:

def to_detail(self) > str:
return _translate(...)

把异常转成对应语言的提示信息。

这意味着:

业务异常

统一错误类型

统一国际化文案

而不是每个 AI 新写一个接口就硬编码:

"User not found"


七、全局异常:异常只需要“抛”,不用到处“接”

miniagent 在应用入口中提供了:

def handle_exception(exc: Exception) > JSONResponse:

统一处理不同类型异常,例如:

Service

NotFoundError

Global Exception Handler

HTTP 404

ApiResponse

对于:

AlreadyExistsError

则统一转成:

HTTP 409 Conflict

其中 Conflict 的意思是:

资源状态冲突。

例如创建一个已经存在的用户名,就很适合这种语义。


未知异常也统一兜底

如果不是已知业务异常:

error_data = {
"error":
str(exc)
if settings.debug
else t("common.error_500")
}

这里体现了一个非常重要的生产环境原则:

开发环境:

可以看到详细错误
方便调试

生产环境:

隐藏内部实现
返回统一错误信息

避免直接把内部异常暴露给普通用户。


八、Validator:错误输入尽量不要进入业务层

再看 miniagent 的用户 Schema。

它没有在创建用户的 API 里面写:

if len(username) < 3:

而是直接定义:

class UserCreate(BaseModel):

username: str = Field(
...,
min_length=3,
max_length=100
)

nickname: Optional[str] = Field(
None,
max_length=100
)

avatar: Optional[str] = Field(
None,
max_length=500
)

这意味着:

用户名长度不合法时,请求还没真正进入核心业务逻辑,就已经被数据模型拦下。


密码校验进一步复用 Validator

miniagent 当前定义:

PasswordValue = Annotated[
str,
Field(max_length=128),
AfterValidator(validate_password)
]

这里出现两个术语。

Annotated

Annotated 可以理解成:

给一个数据类型附加额外规则。

这里基础类型仍然是:

str

但同时增加:

最大长度 128
+
密码 Validator


AfterValidator

AfterValidator 可以理解成:

基础类型校验完成以后,再执行一个自定义校验函数。

这里调用的是:

validate_password

于是创建用户:

class UserCreate(BaseModel):
password: PasswordValue

重置密码:

class UserPasswordReset(BaseModel):
password: PasswordValue

都复用同一套密码规则。

这就是典型的:

一次定义,到处复用。


九、最终形成了一条非常清晰的请求链

把 miniagent 这些真实实现组合起来,可以得到:

miniagent异常架构

于是不同职责变得非常清楚:

Schema / Validator
负责“输入是否合法”

Service
负责“业务能不能做”

Domain Error
负责“业务出了什么问题”

Global Exception Handler
负责“错误怎样转换成 HTTP 响应”

ApiResponse
负责“最后返回长什么样”

这就是统一异常架构真正的价值。


十、架构赋能后的 AI 会怎么写?

假设现在再告诉 AI:

“增加一个修改用户名功能。”

没有架构时,AI 可能从头设计:

参数判断
返回 JSON
try / except
错误信息

有了 miniagent 这样的规则以后,它应该优先思考:

1. UserUpdate 是否已有 username 字段?

2. Field 是否已经规定长度?

3. UserService 中增加业务操作

4. 重名时抛 AlreadyExistsError

5. Router 调用 Service

6. 返回 ApiResponse

而不是重新创造一套规则。

这就是所谓:

架构赋能后的 AI 输出。

不是 AI 突然“更聪明”了,而是:

我们把它可以自由决定的事情减少了。


结语

统一异常与接口封装,看起来只是几个不起眼的基础类:

ApiResponse
PageResult
BaseDomainError
Validator

但对于 AI 编程来说,它们实际上建立了一套非常重要的“交通规则”。

它告诉 AI:

输入怎么检查
成功怎么返回
业务错误怎么表达
系统错误在哪里处理
前端最终看到什么

如果没有这些规则,AI 会在每一个接口里自由发挥;而 AI 越能写代码,这种“不一致”产生得越快。

所以:

好的异常架构,不是为了让代码多几个基类,而是为了让整个系统只有一套错误语言和接口语言。

在 AI 编程时代,更应该把这套规范提前固化进 项目规则 / Project Rules、系统提示词 / System Prompt 或项目上下文中。

最终形成:

输入不合法
→ Validator 拦截

业务不允许
→ Domain Error 表达

系统发生异常
→ Global Handler 兜底

无论成功失败
→ 统一协议返回

这样 AI 每新增一个接口,实际上都在复用同一套工程规则。

不要让 AI 每写一个接口,就重新发明一次“什么叫成功,什么叫失败”。

先统一规则,再让 AI 写业务;这才是统一异常与封装架构在 AI 编程中的真正价值。

开源代码

  • github
  • gitee

🪐祝您好运🪐

赞(0)
未经允许不得转载:171主机测评 » 异常与统一封装架构:规范统一返回值、全局异常与参数校验
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址