文章目录
异常信息
六行井号,对应六个数据:
- activity:目标操作(数据库update)
- resource:目标文件(TagMapper.xml)
- object:目标对象(defaultParameterMap)
- sql:目标SQL语句(insert into tag …)
- message:异常简单描述(Cause …)
- cause:异常数据(下面几行)
对应ErrorContext类的六个成员:
private String resource;
private String activity;
private String object;
private String message;
private String sql;
private Throwable cause;
六个设置方法:
public ErrorContext resource(String resource) {
this.resource = resource;
return this;
}
public ErrorContext activity(String activity) {
this.activity = activity;
return this;
}
public ErrorContext object(String object) {
this.object = object;
return this;
}
public ErrorContext message(String message) {
this.message = message;
return this;
}
public ErrorContext sql(String sql) {
this.sql = sql;
return this;
}
public ErrorContext cause(Throwable cause) {
this.cause = cause;
return this;
}
一个清空方法:
public ErrorContext reset() {
resource = null;
activity = null;
object = null;
message = null;
sql = null;
cause = null;
LOCAL.remove();
return this;
}
统统由一个toString打印出来:
@Override
public String toString() {
StringBuilder description = new StringBuilder();
// message
if (this.message != null) {
description.append(LINE_SEPARATOR);
description.append("### ");
description.append(this.message);
}
// resource
if (resource != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may exist in ");
description.append(resource);
}
// object
if (object != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may involve ");
description.append(object);
}
// activity
if (activity != null) {
description.append(LINE_SEPARATOR);
description.append("### The error occurred while ");
description.append(activity);
}
// sql
if (sql != null) {
description.append(LINE_SEPARATOR);
description.append("### SQL: ");
description.append(sql.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ').trim());
}
// cause
if (cause != null) {
description.append(LINE_SEPARATOR);
description.append("### Cause: ");
description.append(cause.toString());
}
return description.toString();
}
异常的工作流程
以解析XML为例子
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
这里有关异常的两个操作:
抛出异常
throw ExceptionFactory.wrapException(“Error building SqlSession.”, e);
重置异常
ErrorContext.instance().reset();
在try中继续寻找
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
super(new Configuration());
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
这里有关异常的两个操作:
设置异常
ErrorContext.instance().resource(“SQL Mapper Configuration”);
小结:
- try中设置异常,记录当前代码运行的状态。
- catch中抛出异常,将异常信息打印出来。
- finally中清空异常,将记录清除,不影响后续异常。
设置异常
ErrorContext.instance().resource("SQL Mapper Configuration");
public static ErrorContext instance() {
return LOCAL.get();
}
private static final ThreadLocal<ErrorContext> LOCAL = ThreadLocal.withInitial(ErrorContext::new);
ErrorContext,每个线程一个。
抛出异常
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
public static RuntimeException wrapException(String message, Exception e) {
return new PersistenceException(ErrorContext.instance().message(message).cause(e).toString(), e);
}
类关系
class PersistenceException extends IbatisException
class IbatisException extends RuntimeException
这说明最后抛出的是RuntimeException
public static ErrorContext instance() {
return LOCAL.get();
}
这是获取实例
清空异常
这已经展示过了:
public ErrorContext reset() {
resource = null;
activity = null;
object = null;
message = null;
sql = null;
cause = null;
LOCAL.remove();
return this;
}