Skip to content
bitzorcas
中EN

Reference

领域错误模型与枚举定义:Error 与 Result 规范

告别混乱的未捕获异常!深入解析 BitzOrcas.Modern 领域错误定义哲学,掌握 ErrorType 分类、结构化 Error 工厂与 ErrorCatalog 编译期代码生成。

Last updated

在大型团队协作中,如果错误处理没有严格规范,系统很快会变成“异常的垃圾场”:

  • 错误码冲突与重复:模块 A 定义了 UserNotFound,模块 B 也定义了 UserNotFound,但格式与含义各不相同;
  • 随意抛出 RuntimeException:只要发生业务不符就随手 throw new Exception("余额不足"),上层无法区分是网络断开还是业务不满足;
  • 前端国际化困难:错误信息写死在后端代码中,前端无法给海外用户呈现多语言提示。

BitzOrcas.Modern 采用强类型、编译期静态化的 Error + Result<T> 错误流控模型:

错误分类与流转模型

是否 - 400 校验不通过否 - 404 资源不存在否 - 409 业务状态冲突否 - 403 权限拒绝否 - 500 基础设施故障

业务操作评估

是否符合业务不变量?

Result.Success(值)

Error.Validation (参数或规则错误)

Error.NotFound (数据未找到)

Error.Conflict (版本/状态冲突)

Error.Forbidden (越权访问)

Error.Failure (第三方服务降级)


第一步:使用标准工厂创建领域错误

所有业务错误由强类型工厂统一构造,严禁直接 new Exception:

CustomerErrors.cs: 模块级错误定义
using BitzOrcas.Domain.Results;
namespace BitzOrcas.Customer.Domain.Errors;
public static class CustomerErrors
{
// 404: 目标客户不存在
public static readonly Error NotFound = Error.NotFound(
code: "Customer.NotFound",
description: "指定的客户记录不存在。");
// 409: 客户手机号已存在冲突
public static readonly Error PhoneAlreadyExists = Error.Conflict(
code: "Customer.PhoneAlreadyExists",
description: "该手机号已被其他客户绑定。");
// 400: 动态入参校验错误
public static Error InvalidCreditLimit(decimal limit) => Error.Validation(
code: "Customer.InvalidCreditLimit",
description: $"客户授信额度 {limit} 不能为负数。");
}

第二步:在领域与 Handler 中使用 Result 流转

CustomerAggregate.cs: 领域流转
// 领域聚合方法:评估授信额度调整不变量
public Result AdjustCreditLimit(decimal newLimit)
{
// 1. 评估额度是否小于 0
if (newLimit < 0)
{
// 2. 返回强类型错误,零异常栈开销
return Result.Failure(CustomerErrors.InvalidCreditLimit(newLimit));
}
// 3. 业务不变量满足,更新状态并返回成功
CreditLimit = newLimit;
return Result.Success();
}

总结

BitzOrcas 的领域错误模型带来了清晰的协作规范:

  • 零业务异常:GC 零负担,性能大幅提升;
  • 错误码强类型约束:各模块通过前缀(如 Customer.)保证全局命名空间唯一;
  • 自动映射 HTTP 状态码:Validation $ 映射至 HTTP 400,NotFound 映射至 HTTP 404,Conflict 映射至 HTTP 409。

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%