公共sdk异常设计应精简为1–3个runtimeexception子类,含sdkexception(顶层)、sdkserviceexception(服务端错误)和sdkclientexception(客户端错误),错误码需字符串化、文档公开、兼容稳定,禁用受检异常。

在公共 SDK 开发中,自定义异常的设计目标不是“让调用方写更多 try-catch”,而是“让调用方少踩坑、快定位、易集成”。它必须兼顾稳定性、兼容性、可读性和低侵入性。
异常分类要克制,只暴露必要类型
SDK 通常只定义 1–3 个核心异常类,避免泛滥。常见分层方式:
-
SDK 基础异常(如
SdkException):继承RuntimeException,作为所有 SDK 异常的顶层父类,不带业务语义,仅用于统一捕获兜底 -
调用失败异常(如
SdkServiceException):封装服务端返回的错误码、HTTP 状态码、原始响应体等,供高级用户诊断网络或服务问题 -
参数/使用错误异常(如
SdkClientException):表示客户端传参非法、配置缺失、API 调用顺序错误等——这类异常应明确提示“你哪里用错了”,而不是抛出模糊的IllegalArgumentException
构造方法精简,但信息必须可追溯
每个异常类提供以下构造方法即可,不堆砌:
- 仅含错误消息的构造器(方便日志和简单场景)
- 含错误码 + 消息的构造器(关键:错误码建议用字符串,如
"INVALID_API_KEY",比纯数字更稳定、易读、向后兼容) - 含错误码 + 消息 + cause 的构造器(保留异常链,便于排查底层依赖问题)
不建议在异常中直接塞 JSON 响应体或大段上下文——这些应由 SDK 内部日志系统记录,异常对象本身保持轻量。
错误码设计要公开、稳定、带语义
所有业务级错误码需在 SDK 文档中明确定义,并承诺长期兼容:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 格式统一,例如
SDK_AUTH_001(模块_序号)或MISSING_REQUIRED_PARAM(全大写下划线) - 避免用 HTTP 状态码直接作错误码(如
401),因为 SDK 可能跨协议(gRPC、WebSocket 等),语义不通用 - 提供静态工厂方法,如
SdkClientException.missingApiKey(),降低用户构造异常的成本,也便于未来统一增强逻辑
绝不抛出受检异常(Checked Exception)
公共 SDK 必须全部使用 RuntimeException 子类:
- 调用方可能是 Kotlin、Groovy 或脚本语言环境,受检异常会破坏语法简洁性
- 强制 throws 会污染所有上层接口签名,违背“SDK 应轻量接入”原则
- 真实场景中,95% 的 SDK 错误无法被调用方程序性恢复(比如网络不通、密钥失效),强制捕获反而诱导写出空 catch 或吞异常
若需强调某类错误必须处理(如鉴权失败后跳登录页),应通过文档 + 示例代码 + IDE 提示(如注释 @see)引导,而非编译强制。
配套支持:异常与日志、监控联动
SDK 内部应在抛出异常前,自动记录结构化日志(含 traceId、errorCode、method、params 等),并支持对接主流日志框架(SLF4J);同时预留扩展点,允许用户注册全局异常处理器,用于上报监控或触发重试逻辑。
不复杂但容易忽略:异常类本身必须实现 Serializable,并显式声明 serialVersionUID——尤其当 SDK 用于分布式链路(如 Dubbo、Spring Cloud)时,否则反序列化会失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










