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

Avoid catching Throwable.

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