Rust 错误处理模式与生产级代码组织:流量上来前要补哪些防线

Rust 错误处理模式与生产级代码组织:流量上来前要补哪些防线

我把“流量上来”换成可测试的边界:输入过大、重复提交和下游超时。先在入口限制大小,错误统一映射成不会泄露内部细节的类型。

if input.len() > MAX_BYTES { return Err(AppError::InputTooLarge); }

然后为超时写测试,确认调用者能看到可重试或不可重试的区别。这里没有真实流量数据,不能估算容量;我能做的是把明显的无限等待和无界输入先关掉。

错误类型先服务于决策,不是服务于排版

Rust 项目里常见的两种极端是:所有地方直接返回 Box<dyn Error>,或者为每个底层异常都复制一套业务类型。前者让调用方几乎无法做判断,后者又会把转换代码铺满整个项目。更实用的边界是按调用者需要的动作分类,例如输入问题、依赖暂时不可用、依赖拒绝请求、内部错误。上层据此决定提示用户、重试、告警或中断流程;底层错误作为 source 保留下来,供日志和排障使用。

不要把数据库驱动、HTTP 客户端或解析库的错误类型从核心业务接口直接泄出去。那会让业务代码绑定具体实现,也会让将来替换依赖变得昂贵。适配层负责把底层错误转换成应用错误,并补上发生操作所需的上下文,例如是在读取配置、写入记录还是调用远端服务。上下文应描述动作,不能把令牌、完整请求体或用户数据塞进错误消息。

入口限制需要和资源模型对应

MAX_BYTES 这样的限制只有在定义清楚时才有意义:它约束的是原始请求、解压后的内容、单个字段还是整个批次?如果在网络入口限制了压缩包大小,却在解压后允许无限膨胀,风险仍然存在。同样,字符串长度、集合条目数和嵌套层级可能都需要各自的边界。评审时可以把这些检查放在解析前或分配大对象前,避免错误输入已经占用大量内存才被拒绝。

重复提交也不只是“看到相同请求就报错”。要明确重复的判定键、判定窗口和并发到达时的行为。对于有副作用的操作,最好让存储层或下游接口具备幂等语义;仅靠内存中的标记,在进程重启或多实例下并不可靠。若现有系统没有这样的能力,至少不要在错误处理里悄悄重放写操作,避免把一次超时扩大成多次提交。

超时以后,还要决定结果归谁

给远端调用加超时,只解决了调用者不再无限等的问题。超时之后请求可能已经到达服务端,服务端也可能仍在执行。因此错误类型中“可重试”不能只看本地超时,还要结合操作是否安全重试、是否有幂等键、是否已经拿到部分响应。对读取操作和带副作用的写操作,重试策略通常不能照搬。

测试不应只断言返回了 timeout。还要确认取消或截止时间是否传递到下游,连接是否会被正确归还,失败日志是否包含足够的关联信息。可以用可控的假依赖模拟慢响应、连接断开和先成功后失败等情形,观察调用方是否把错误归类正确。这样测试覆盖的是决策路径,而不是碰巧触发了一次异常。

组织代码时把转换放在边界处

业务函数保持返回应用层的结果类型,外部协议层负责把它映射成 HTTP 状态、命令行退出码或消息队列确认结果。这样同一个领域错误在不同入口下可以有不同表达,不会把某个传输协议的概念混入核心逻辑。日志和指标也放在边界附近:记录一次失败即可,避免每层都打印同一个错误造成噪声。

没有真实流量数据时,容量结论仍应留白。先限制无界输入、为等待设置截止时间、补齐重复提交和下游失败的测试,这些改动能直接降低明显风险。之后再根据真实的请求大小、耗时分布和失败率决定阈值与并发策略,而不是凭一段代码估算系统能扛多少流量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值