Kratos错误提示国际化必须两级解耦:ErrorReason枚举仅定义语义和状态码,文案由messages_*.properties按Locale动态解析,Key须严格对齐,新增语言只需添加对应资源文件。

Kratos 的错误提示国际化不能靠改 Error().Error() 或硬塞中文字符串,必须用 errors + MessageSource 两级解耦:错误码枚举定义语义,资源文件承载文案,框架层按 Locale 动态解析。
kratos.errors 中的 ErrorReason 枚举怎么配多语言 key
Key 不是随便起的字符串,而是要和资源文件严格对齐的标识符。Kratos 自带的 ErrorReason 枚举只负责定义业务语义和 HTTP/gRPC 状态码,不存文案——文案交由外部 messages_*.properties 管理。
-
ErrorReason.USER_NOT_FOUND对应资源文件里的键USER_NOT_FOUND,大小写、下划线必须完全一致 - 枚举项上加
[(errors.code)=404]是为了绑定状态码,不影响文案查找路径 - 新增语言时,不用改任何 .proto 或生成代码,只加
messages_ja_JP.properties文件即可 - 如果某条 key 在当前语言包里缺失,
MessageSource默认 fallback 到messages.properties(即默认英文),不是报错或空字符串
MessageSource 怎么加载多语言资源并 fallback
Kratos 本身不内置 MessageSource,得自己配 Spring 的 ResourceBundleMessageSource 或用 ReloadableResourceBundleMessageSource 支持热更新。关键在 basename 和 fallback 配置。
- basename 设为
i18n/messages,这样会自动加载i18n/messages_zh_CN.properties、i18n/messages_en_US.properties等 - 必须设
setFallbackToSystemLocale(false),否则用户传zh却没注册zh包时,会悄悄 fallback 到系统 locale(比如服务器是 en-US),而不是你期望的en_US - 推荐设
setDefaultEncoding("UTF-8"),避免 properties 文件里中文乱码 - 占位符统一用
{0}、{1},和MessageFormat兼容,不要用%s或{name}
ControllerAdvice 怎么把枚举 error 映射成带 locale 的提示
不能在异常抛出时就调用 getMessage(),而要在全局异常处理器里,用当前请求的 Locale 去查 —— 这样才能响应 Accept-Language: zh-CN 或 X-Lang: ja-JP。
- 从
HttpServletRequest提取Locale:优先看X-Langheader, fallback 到request.getLocale() - 异常对象里必须能拿到原始枚举项(比如
BusinessException包着ErrorReason.USER_NOT_FOUND),不能只存一个字符串 message - 调用
messageSource.getMessage(reason.name(), args, locale),args是运行期参数,如new Object[]{"alice"} - 最终 JSON 响应结构保持统一:
{"code":404,"reason":"USER_NOT_FOUND","message":"用户 alice 不存在"},前端可直接展示message
为什么 kratos.errors 生成的 Go 代码不直接支持多语言
因为 protoc-gen-go-errors 生成的是错误码定义和 gRPC/HTTP 映射逻辑,它不碰文案——文案属于应用层职责。生成的 xxx_errors.pb.go 里只有 GRPCStatus() 和 HTTPCode() 方法,没有 LocalizedMessage()。
- 如果你在 Go 层也想做多语言,得自己封装一层,比如
LocalizedError类型,内部持ErrorReason和Args,再配golang.org/x/text/message渲染 - 切记:不要重写
Error()方法返回本地化文本,日志里全是中文会让后端排查崩溃 - Go 侧的
localetag 必须用language.Make("zh-CN")构造,手拼"zh-CN"字符串容易因大小写或分隔符不匹配导致 fallback 失败 - 同一个
ErrorReason在 Java 和 Go 两端要用同一套messages_*.properties,确保中英日文案一致,避免客服查工单时看到三个版本
最易被忽略的一点:错误消息的多语言不是“翻译完就完事”,而是要保证 reason 字段稳定、message 字段可变、args 字段可序列化。一旦 reason 被前端当 key 缓存,或被日志系统按字段聚合,改 key 就等于断裂兼容性。


















