提交 c58f4eaa authored 作者: Thomas Mueller's avatar Thomas Mueller

Avoid catching Throwable.

上级 d8c3a8fb
......@@ -206,9 +206,6 @@ public abstract class Command implements CommandInterface {
database.checkPowerOff();
try {
return update();
} catch (OutOfMemoryError e) {
MemoryUtils.freeReserveMemory();
throw Message.convert(e);
} catch (SQLException e) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
long now = System.currentTimeMillis();
......@@ -227,8 +224,10 @@ public abstract class Command implements CommandInterface {
continue;
}
throw e;
} catch (Throwable e) {
} catch (Exception e) {
throw Message.convert(e);
} catch (Throwable e) {
throw Message.convertThrowable(e);
}
}
} catch (SQLException e) {
......
......@@ -60,6 +60,7 @@ import org.h2.util.BitField;
import org.h2.util.ByteUtils;
import org.h2.util.ClassUtils;
import org.h2.util.FileUtils;
import org.h2.util.MemoryUtils;
import org.h2.util.NetUtils;
import org.h2.util.New;
import org.h2.util.ObjectArray;
......@@ -218,6 +219,7 @@ public class Database implements DataHandler {
private void openDatabase(int traceLevelFile, int traceLevelSystemOut, boolean closeAtVmShutdown) throws SQLException {
try {
MemoryUtils.allocateReserveMemory();
open(traceLevelFile, traceLevelSystemOut);
if (closeAtVmShutdown) {
try {
......@@ -234,6 +236,10 @@ public class Database implements DataHandler {
}
}
} catch (Throwable e) {
if (e instanceof OutOfMemoryError) {
MemoryUtils.freeReserveMemory();
e.fillInStackTrace();
}
if (traceSystem != null) {
if (e instanceof SQLException) {
SQLException e2 = (SQLException) e;
......@@ -245,7 +251,10 @@ public class Database implements DataHandler {
traceSystem.close();
}
closeOpenFilesAndUnlock(false);
throw Message.convert(e);
if (e instanceof Error) {
throw (Error) e;
}
throw Message.convert((Exception) e);
}
}
......@@ -1157,19 +1166,23 @@ public class Database implements DataHandler {
}
try {
if (systemSession != null) {
for (Table table : getAllTablesAndViews()) {
table.close(systemSession);
}
for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) {
Sequence sequence = (Sequence) obj;
sequence.close();
if (powerOffCount != -1) {
for (Table table : getAllTablesAndViews()) {
table.close(systemSession);
}
for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) {
Sequence sequence = (Sequence) obj;
sequence.close();
}
}
for (SchemaObject obj : getAllSchemaObjects(DbObject.TRIGGER)) {
TriggerObject trigger = (TriggerObject) obj;
trigger.close();
}
meta.close(systemSession);
systemSession.commit(true);
if (powerOffCount != -1) {
meta.close(systemSession);
systemSession.commit(true);
}
indexSummaryValid = true;
}
} catch (SQLException e) {
......
......@@ -314,8 +314,10 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
className = StringUtils.trim(className, true, true, "'");
try {
eventListener = (DatabaseEventListener) ClassUtils.loadUserClass(className).newInstance();
} catch (Throwable e) {
} catch (Exception e) {
throw Message.convert(e);
} catch (Throwable e) {
throw Message.convertThrowable(e);
}
}
}
......
......@@ -386,7 +386,7 @@ public class LogFile {
// this is not necessarily at the end of the log file
// set the log system to read only so the current log file stays when closing
logSystem.setReadOnly(true);
throw Message.convert(e);
throw Message.convertThrowable(e);
} catch (Throwable e) {
database.getTrace(Trace.LOG).error("Error reading log file (non-fatal)", e);
// on power loss, sometime there is garbage at the end of the file
......
......@@ -187,11 +187,10 @@ public class LogSystem {
if (!containsInDoubtTransactions() && checkpoint) {
checkpoint();
}
} catch (SQLException e) {
closeException = e;
} catch (Throwable e) {
// for example out of memory exception
} catch (Exception e) {
closeException = Message.convert(e);
} catch (Throwable e) {
closeException = Message.convertThrowable(e);
}
for (int i = 0; i < activeLogs.size(); i++) {
LogFile l = activeLogs.get(i);
......
......@@ -17,6 +17,7 @@ import java.util.Map.Entry;
import org.h2.constant.ErrorCode;
import org.h2.jdbc.JdbcSQLException;
import org.h2.util.MemoryUtils;
import org.h2.util.Resources;
import org.h2.util.StringUtils;
......@@ -239,7 +240,7 @@ public class Message {
* @param sql the SQL statement or null if it is not known
* @return the SQL exception object
*/
public static SQLException convert(Throwable e, String sql) {
public static SQLException convert(Exception e, String sql) {
SQLException e2 = convert(e);
if (e2 instanceof JdbcSQLException) {
((JdbcSQLException) e2).setSQL(sql);
......@@ -247,20 +248,28 @@ public class Message {
return e2;
}
/**
* Convert a stack overflow error.
*
* @param e the root cause
* @return the SQL exception object
*/
public static SQLException convert(StackOverflowError e) {
return getSQLException(ErrorCode.GENERAL_ERROR_1, e);
}
/**
* Convert an exception to a SQL exception using the default mapping.
*
* @param e the root cause
* @return the SQL exception object
*/
public static SQLException convert(Throwable e) {
public static SQLException convert(Exception e) {
if (e instanceof InternalException) {
e = ((InternalException) e).getOriginalCause();
}
if (e instanceof SQLException) {
return (SQLException) e;
} else if (e instanceof OutOfMemoryError) {
return getSQLException(ErrorCode.OUT_OF_MEMORY, e);
} else if (e instanceof InvocationTargetException) {
InvocationTargetException te = (InvocationTargetException) e;
Throwable t = te.getTargetException();
......@@ -274,6 +283,29 @@ public class Message {
return getSQLException(ErrorCode.GENERAL_ERROR_1, e, e.toString());
}
/**
* Convert a throwable to an SQL exception using the default mapping. For
* out of memory errors, this will first try to free up some memory, and if
* not possible it will re-throw the error. All errors except the following
* are re-thrown: StackOverflowError, LinkageError.
*
* @param e the root cause
* @return the SQL exception object
*/
public static SQLException convertThrowable(Throwable e) {
if (e instanceof OutOfMemoryError) {
if (MemoryUtils.freeReserveMemory()) {
return getSQLException(ErrorCode.OUT_OF_MEMORY, e);
}
throw (OutOfMemoryError) e;
} else if (e instanceof StackOverflowError || e instanceof LinkageError) {
return getSQLException(ErrorCode.GENERAL_ERROR_1, e, e.toString());
} else if (e instanceof Error) {
throw (Error) e;
}
return getSQLException(ErrorCode.GENERAL_ERROR_1, e, e.toString());
}
/**
* Convert an IO exception to a SQL exception.
*
......
......@@ -405,8 +405,10 @@ public class TcpServer implements Service {
String db = getManagementDbName(port);
try {
org.h2.Driver.load();
} catch (Throwable e) {
} catch (Exception e) {
throw Message.convert(e);
} catch (Throwable e) {
throw Message.convertThrowable(e);
}
for (int i = 0; i < 2; i++) {
Connection conn = null;
......
......@@ -184,7 +184,12 @@ public class TcpServerThread implements Runnable {
private void sendError(Throwable e) {
try {
SQLException s = Message.convert(e);
SQLException s;
if (e instanceof Exception) {
s = Message.convert((Exception) e);
} else {
s = Message.convertThrowable(e);
}
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String trace = writer.toString();
......
......@@ -140,7 +140,10 @@ public class TableData extends Table implements RecordReader {
trace.error("Could not undo operation", e);
throw e2;
}
throw Message.convert(e);
if (e instanceof Exception) {
throw Message.convert((Exception) e);
}
throw Message.convertThrowable(e);
}
}
......@@ -380,7 +383,10 @@ public class TableData extends Table implements RecordReader {
trace.error("Could not undo operation", e);
throw e2;
}
throw Message.convert(e);
if (e instanceof Exception) {
throw Message.convert((Exception) e);
}
throw Message.convertThrowable(e);
}
}
......
......@@ -90,9 +90,15 @@ public class MemoryUtils {
/**
* Free up the reserve memory.
*
* @return if memory could be freed up.
*/
public static void freeReserveMemory() {
public static boolean freeReserveMemory() {
if (reserveMemory == null) {
return false;
}
reserveMemory = null;
return true;
}
/**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论