checked exception 和 unchecked exception
- checked exception:编译器检查的异常,必须处理
- unchecked exception:运行时异常,编译器不检查的异常
摒弃checked exception, 全部使用unchecked exception, 使用 RuntimeException 作为所有运行时异常的父类,
引擎使用 SnestException 作为所有异常的父类.
引擎异常使用
/**
* 引擎异常基类,其他异常都需要继承此
*
* @author
*/
public class SnestException extends RuntimeException {
private ErrorCode errorEnum = ErrorCode.UNKNOWN_EXC;
private Integer errorCode;
private String messageFormat;
private Object[] args;
/**
* 返回国际化翻译过后的错误信息
*
* @return
*/
@Override
public String getMessage() {
return this.messageFormat == null ||
"".equals(this.messageFormat.trim()) ? super.getMessage() : MultiLangUtil.l10n(this.messageFormat, this.args);
}
/**
* 获取多语言的错误信息(从上下文meta中获取当前语言)
*
* @return 多语言的错误信息
*/
@Override
public String getLocalizedMessage() {
return MultiLangUtil.l10n(this.messageFormat, this.args);
}
}
SnestException 类包含 ErrorCode 枚举,ErrorCode 枚举包含了所有的错误码和错误信息,使用时直接创建即可,SnestException 会自动格式化对应的错误信息。
如果自定义错误信息,SnestException 会自动格式化对应的错误信息。
也可以继承 SnestException 类,重写 getMessage() 方法,返回自定义的错误信息。
异常也可以继续传递给下一个异常,形成异常链。
public class AccessException extends SnestException {
protected static ErrorCode errorCode = ErrorCode.ACCESS_EXC;
public AccessException() {
super(errorCode);
}
public AccessException(Throwable cause) {
super(errorCode, cause);
}
public AccessException(String message) {
super(errorCode.getCode(), message);
}
public AccessException(String message, Throwable cause) {
super(errorCode.getCode(), message, cause);
}
public AccessException(String messageFormat, Object... args) {
super(errorCode.getCode(), messageFormat, args);
}
public AccessException(Throwable cause, String messageFormat, Object... args) {
super(cause, errorCode.getCode(), null, messageFormat, args);
}
}
public class EngineException extends SnestException {
// 定义错误码
protected static ErrorCode errorEnum = ErrorCode.ENGINE_EXC;
public EngineException() {
super(errorEnum);
}
public EngineException(Throwable cause) {
super(errorEnum, cause);
}
public EngineException(String message) {
super(errorEnum.getCode(), message);
}
public EngineException(String message, Throwable cause) {
super(errorEnum.getCode(), message, cause);
}
public EngineException(String message, int errorCode) {
super(errorCode, message);
}
public EngineException(int errorCode, String messageFormat, Object... args) {
super(errorCode, messageFormat, args);
}
public EngineException(String messageFormat, Object... args) {
super(errorEnum.getCode(), messageFormat, args);
}
public EngineException(Throwable cause, String messageFormat, Object... args) {
super(cause, errorEnum.getCode(), null, messageFormat, args);
}
}
错误码定义
/**
* 错误码,统一在此处定义
*
* @author xiaomi
*/
public enum ErrorCode {
/**
* 错误日志对照表
*/
ARGUMENT_NULL_EXC(100, "参数为空异常"),
DATA_FORMAT_EXC(101, "数据格式异常"),
VALUE_EXC(105, "值异常(值的范围、格式、类型不符合预期)"),
DATA_EXC(200, "数据异常,数据持久化失败"),
DB_EXC(201, "执行DB操作异常"),
SQL_PARSE_EXC(205, "SQL解析异常"),
MISSING_EXC(300, "缺失异常(找不到期望的参数、值、对象等)"),
DATA_MISSING_EXC(335, "数据异常"),
UNSUPPORTED_EXC(341, "暂不支持异常"),
/** 擎相关 */
ENGINE_EXC(400, "引擎内部异常"),
UNAUTHORIZED_EXC(401, "未登录"),
FORBIDDEN_EXC(403, "无权限访问"),
APP_EXC(405, "APP异常"),
META_EXC(500, "元模型异常"),
MODEL_EXC(504, "模型异常"),
SERVICE_ORCHESTRATE_EXC(505, "元模型异常,元模型定义不符合要求导致建构元模型失败"),
CALL_EXC(600, "call调用服务(方法)异常"),
PROXY_EXC(601, "动/静态代理执行异常"),
REFLECT_EXC(602, "反射执行异常"),
SIDE_CAR_EXC(630, "分布式sideCar异常"),
UNKNOWN_EXC(999, "未知异常"),
USER_EXC(1000, "用户异常"),
VALIDATION_EXC(2000, "校验失败"),
ACCESS_EXC(7000, "访问异常"),
REDIS_MODEL_META(10000, "引擎Redis异常"),
REDIS_FINAL_MODEL(10000, "引擎Redis异常,模型终态数据有误."),
REDIS_PROPERTY_META(10001, "引擎Redis异常,属性初态数据有误."),
REDIS_METHOD_META(10002, "引擎Redis异常,方法初态数据有误."),
REDIS_SERVICE_META(10003, "引擎Redis异常,服务初态数据有误."),
REDIS_PARAM_META(10004, "引擎Redis异常,服务参数初态数据有误."),
SIDE_CAR_NOT_FOUND_APP(15000, "未找到应用: %s"),
SIDE_CAR_INSTALLING_APP(15001, "正在安装应用: %s"),
ENGINE_PLUGIN(20000, "引擎插件异常"),
// SDK 相关
SDK_EXC(21000, "SDK异常"),
;
private static final Map<Integer, ErrorCode> ERROR_CODE_MAP = convertToErrorCodeMap();
private int code;
private String msg;
ErrorCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public static Map<Integer, ErrorCode> getErrorCodeMap() {
return ERROR_CODE_MAP;
}
private static Map<Integer, ErrorCode> convertToErrorCodeMap() {
return Arrays.stream(ErrorCode.values()).collect(Collectors.toMap(e -> e.code, Function.identity(), (prev, next) -> next));
}
}
/*
错误码规则:
xx xx xx
两位代表具体的app 两位代表具体app中某个model 具体业务类型的具体的错误类型
举例:120200
12 02 00
操作日志app 黑名单类型 黑名单参数异常
*/
// 公共错误码 10
const (
ErrUnknown = -1
ErrOk = 0
ErrParameterInvalid = 100001
ErrInternalServerError = 100002
ErrRequestTimeout = 100003
ErrCallServiceTimeout = 100004
)
var errTextMap = map[int]string{
ErrUnknown: "未知错误",
ErrOk: "成功",
ErrParameterInvalid: "请求参数错误",
ErrInternalServerError: "服务内部错误",
ErrRequestTimeout: "请求超时,请稍后重试",
ErrCallServiceTimeout: "调用服务超时",
}