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