企業級應用中,自訂異常不僅是「拋出錯誤」,更需支援錯誤碼標準化、多語系訊息、統一異常攔截。本文展示一個生產級 MyException 設計範例,涵蓋枚舉錯誤碼、鏈式異常、資源包整合要點。
cause 鏈,不丟失根因。serialVersionUID。public class MyException extends Exception {
private static final long serialVersionUID = 1L;
private final Type type;
public MyException(Type type) {
this.type = type;
}
public MyException(Throwable cause, Type type) {
super(cause);
this.type = type;
}
@Override
public String toString() {
return super.toString() + "<" + type.getErrorCode() + ">";
}
public Type getErrorType() { return type; }
public enum Type {
SYSTEM_ERROR("99999"),
USER_AUTH("03003"),
PARAM_INVALID("04001"),
BIZ_RULE_VIOLATION("05001");
private final String errorCode;
Type(String errorCode) { this.errorCode = errorCode; }
public String getErrorCode() { return errorCode; }
}
}
// Service 層拋出
if (!userService.authenticate(token)) {
throw new MyException(MyException.Type.USER_AUTH);
}
// Controller 統一攔截 (Spring @ControllerAdvice)
@ExceptionHandler(MyException.class)
public Result handle(MyException e) {
String msg = messageSource.getMessage(e.getErrorType().getErrorCode(), null, LocaleContextHolder.getLocale());
return Result.fail(e.getErrorType().getErrorCode(), msg);
}
在 src/main/resources/messages.properties 及 messages_zh_TW.properties 定義:
# messages.properties
03003=Authentication failed
99999=System error
# messages_zh_TW.properties
03003=使用者認證失敗
99999=系統錯誤
Spring MessageSource 會自動依 Locale 解析對應訊息,前端無需硬編碼文字。
toString() 附帶錯誤碼,方便 ELK/日誌平台檢索聚合。規範的自訂異常體系,能讓錯誤處理從「亂碼堆疊」變成「可追蹤、可國際化、可自動化」的工程資產。