提交 8ae62962 authored 作者: andrei's avatar andrei

More places to catch unchecked exception (including OOM) and convert to SQLExceptions

上级 29abf234
...@@ -69,7 +69,8 @@ class DatabaseCloser extends Thread { ...@@ -69,7 +69,8 @@ class DatabaseCloser extends Thread {
trace.error(e, "could not close the database"); trace.error(e, "could not close the database");
// if this was successful, we ignore the exception // if this was successful, we ignore the exception
// otherwise not // otherwise not
} catch (RuntimeException e2) { } catch (Throwable e2) {
e.addSuppressed(e2);
throw e; throw e;
} }
} }
......
...@@ -411,7 +411,7 @@ public class JdbcConnection extends TraceObject ...@@ -411,7 +411,7 @@ public class JdbcConnection extends TraceObject
session = null; session = null;
} }
} }
} catch (Exception e) { } catch (Throwable e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
} }
......
...@@ -248,7 +248,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements ...@@ -248,7 +248,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
} finally { } finally {
afterWriting(); afterWriting();
} }
} catch (Exception e) { } catch (Throwable e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
} }
......
...@@ -273,7 +273,7 @@ public class DbException extends RuntimeException { ...@@ -273,7 +273,7 @@ public class DbException extends RuntimeException {
* @param e the root cause * @param e the root cause
* @return the SQL exception object * @return the SQL exception object
*/ */
public static SQLException toSQLException(Exception e) { public static SQLException toSQLException(Throwable e) {
if (e instanceof SQLException) { if (e instanceof SQLException) {
return (SQLException) e; return (SQLException) e;
} }
......
...@@ -351,17 +351,25 @@ public class TraceObject { ...@@ -351,17 +351,25 @@ public class TraceObject {
* @param ex the exception * @param ex the exception
* @return the SQL exception object * @return the SQL exception object
*/ */
protected SQLException logAndConvert(Exception ex) { protected SQLException logAndConvert(Throwable ex) {
SQLException e = DbException.toSQLException(ex); SQLException e = null;
if (trace == null) { try {
DbException.traceThrowable(e); e = DbException.toSQLException(ex);
} else { if (trace == null) {
int errorCode = e.getErrorCode(); DbException.traceThrowable(e);
if (errorCode >= 23000 && errorCode < 24000) {
trace.info(e, "exception");
} else { } else {
trace.error(e, "exception"); int errorCode = e.getErrorCode();
if (errorCode >= 23000 && errorCode < 24000) {
trace.info(e, "exception");
} else {
trace.error(e, "exception");
}
}
} catch(Throwable ignore) {
if (e == null) {
e = new SQLException("", "HY000", ex);
} }
e.addSuppressed(ignore);
} }
return e; return e;
} }
......
...@@ -380,9 +380,7 @@ public final class MVStore { ...@@ -380,9 +380,7 @@ public final class MVStore {
} }
private void panic(IllegalStateException e) { private void panic(IllegalStateException e) {
if (backgroundExceptionHandler != null) { handleException(e);
backgroundExceptionHandler.uncaughtException(null, e);
}
panicException = e; panicException = e;
closeImmediately(); closeImmediately();
throw e; throw e;
...@@ -862,10 +860,8 @@ public final class MVStore { ...@@ -862,10 +860,8 @@ public final class MVStore {
public void closeImmediately() { public void closeImmediately() {
try { try {
closeStore(false); closeStore(false);
} catch (Exception e) { } catch (Throwable e) {
if (backgroundExceptionHandler != null) { handleException(e);
backgroundExceptionHandler.uncaughtException(null, e);
}
} }
} }
...@@ -2468,11 +2464,9 @@ public final class MVStore { ...@@ -2468,11 +2464,9 @@ public final class MVStore {
if (hasUnsavedChanges()) { if (hasUnsavedChanges()) {
try { try {
commitAndSave(); commitAndSave();
} catch (Exception e) { } catch (Throwable e) {
if (backgroundExceptionHandler != null) { handleException(e);
backgroundExceptionHandler.uncaughtException(null, e); return;
return;
}
} }
} }
if (autoCompactFillRate > 0) { if (autoCompactFillRate > 0) {
...@@ -2492,10 +2486,18 @@ public final class MVStore { ...@@ -2492,10 +2486,18 @@ public final class MVStore {
// in the bookkeeping? // in the bookkeeping?
compact(fillRate, autoCommitMemory); compact(fillRate, autoCommitMemory);
autoCompactLastFileOpCount = fileStore.getWriteCount() + fileStore.getReadCount(); autoCompactLastFileOpCount = fileStore.getWriteCount() + fileStore.getReadCount();
} catch (Exception e) { } catch (Throwable e) {
if (backgroundExceptionHandler != null) { handleException(e);
backgroundExceptionHandler.uncaughtException(null, e); }
} }
}
private void handleException(Throwable ex) {
if (backgroundExceptionHandler != null) {
try {
backgroundExceptionHandler.uncaughtException(null, ex);
} catch(Throwable ignore) {
ex.addSuppressed(ignore);
} }
} }
} }
......
...@@ -79,6 +79,8 @@ public abstract class TestBase { ...@@ -79,6 +79,8 @@ public abstract class TestBase {
private final LinkedList<byte[]> memory = new LinkedList<>(); private final LinkedList<byte[]> memory = new LinkedList<>();
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
/** /**
* Get the test directory for this test. * Get the test directory for this test.
* *
...@@ -545,7 +547,6 @@ public abstract class TestBase { ...@@ -545,7 +547,6 @@ public abstract class TestBase {
* @param s the message * @param s the message
*/ */
static synchronized void printlnWithTime(long millis, String s) { static synchronized void printlnWithTime(long millis, String s) {
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
s = dateFormat.format(new java.util.Date()) + " " + s = dateFormat.format(new java.util.Date()) + " " +
formatTime(millis) + " " + s; formatTime(millis) + " " + s;
System.out.println(s); System.out.println(s);
...@@ -1470,6 +1471,12 @@ public abstract class TestBase { ...@@ -1470,6 +1471,12 @@ public abstract class TestBase {
*/ */
protected void freeMemory() { protected void freeMemory() {
memory.clear(); memory.clear();
for (int i = 0; i < 5; i++) {
System.gc();
try {
Thread.sleep(20);
} catch (InterruptedException ignore) {/**/}
}
} }
/** /**
......
...@@ -15,6 +15,7 @@ import java.util.Map; ...@@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.mvstore.MVStore; import org.h2.mvstore.MVStore;
import org.h2.store.fs.FilePath; import org.h2.store.fs.FilePath;
import org.h2.store.fs.FilePathMem; import org.h2.store.fs.FilePathMem;
...@@ -142,7 +143,7 @@ public class TestOutOfMemory extends TestBase { ...@@ -142,7 +143,7 @@ public class TestOutOfMemory extends TestBase {
} }
private void testUpdateWhenNearlyOutOfMemory() throws SQLException, InterruptedException { private void testUpdateWhenNearlyOutOfMemory() throws SQLException, InterruptedException {
if (config.memory || config.mvcc || config.mvStore) { if (config.memory) {
return; return;
} }
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
...@@ -161,8 +162,26 @@ public class TestOutOfMemory extends TestBase { ...@@ -161,8 +162,26 @@ public class TestOutOfMemory extends TestBase {
stat.execute("checkpoint"); stat.execute("checkpoint");
eatMemory(80); eatMemory(80);
try { try {
assertThrows(ErrorCode.OUT_OF_MEMORY, prep).execute(); try {
assertThrows(ErrorCode.DATABASE_IS_CLOSED, conn).close(); prep.execute();
fail();
} catch(DbException ex) {
freeMemory();
assertEquals(ErrorCode.OUT_OF_MEMORY, ex.getErrorCode());
} catch (SQLException ex) {
freeMemory();
assertEquals(ErrorCode.OUT_OF_MEMORY, ex.getErrorCode());
}
try {
conn.close();
fail();
} catch(DbException ex) {
freeMemory();
assertEquals(ErrorCode.DATABASE_IS_CLOSED, ex.getErrorCode());
} catch (SQLException ex) {
freeMemory();
assertEquals(ErrorCode.DATABASE_IS_CLOSED, ex.getErrorCode());
}
freeMemory(); freeMemory();
conn = null; conn = null;
conn = getConnection("outOfMemory"); conn = getConnection("outOfMemory");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论