Log more specific database exceptions.
This commit is contained in:
parent
13ef53372e
commit
00c131355f
2 changed files with 47 additions and 9 deletions
|
@ -9,6 +9,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
|||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
/**
|
||||
* The default error handler wipes the file. This one instead prints some diagnostics and then crashes so the original corrupt file isn't lost.
|
||||
|
@ -24,30 +25,60 @@ public final class SqlCipherErrorHandler implements DatabaseErrorHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public void onCorruption(SQLiteDatabase db) {
|
||||
Log.e(TAG, "Database '" + databaseName + "' corrupted! Going to try to run some diagnostics.");
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
Log.w(TAG, " ===== PRAGMA integrity_check =====");
|
||||
output.append("Database '").append(databaseName).append("' corrupted! Going to try to run some diagnostics.").append("\n");
|
||||
|
||||
boolean pragma1Passes = false;
|
||||
boolean pragma2Passes = true;
|
||||
|
||||
output.append(" ===== PRAGMA integrity_check =====").append("\n");
|
||||
try (Cursor cursor = db.rawQuery("PRAGMA integrity_check", null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
Log.w(TAG, CursorUtil.readRowAsString(cursor));
|
||||
String row = CursorUtil.readRowAsString(cursor);
|
||||
output.append(row).append("\n");
|
||||
if (row.toLowerCase().contains("ok")) {
|
||||
pragma1Passes = true;
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "Failed to do integrity_check!", t);
|
||||
output.append("Failed to do integrity_check!").append("\n")
|
||||
.append(Util.convertThrowableToString(t));
|
||||
}
|
||||
|
||||
Log.w(TAG, "===== PRAGMA cipher_integrity_check =====");
|
||||
output.append("\n").append("===== PRAGMA cipher_integrity_check =====").append("\n");
|
||||
try (Cursor cursor = db.rawQuery("PRAGMA cipher_integrity_check", null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
Log.w(TAG, CursorUtil.readRowAsString(cursor));
|
||||
output.append(CursorUtil.readRowAsString(cursor)).append("\n");
|
||||
pragma2Passes = false;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "Failed to do cipher_integrity_check!", t);
|
||||
output.append("Failed to do cipher_integrity_check!").append("\n")
|
||||
.append(Util.convertThrowableToString(t));
|
||||
}
|
||||
|
||||
throw new DatabaseCorruptedError();
|
||||
Log.e(TAG, output.toString());
|
||||
|
||||
if (pragma1Passes && pragma2Passes) {
|
||||
throw new DatabaseCorruptedError_BothChecksPass();
|
||||
} else if (!pragma1Passes && pragma2Passes) {
|
||||
throw new DatabaseCorruptedError_NormalCheckFailsCipherCheckPasses();
|
||||
} else if (pragma1Passes && !pragma2Passes) {
|
||||
throw new DatabaseCorruptedError_NormalCheckPassesCipherCheckFails();
|
||||
} else {
|
||||
throw new DatabaseCorruptedError_BothChecksFail();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DatabaseCorruptedError extends Error {
|
||||
|
||||
public static final class DatabaseCorruptedError_BothChecksPass extends Error {
|
||||
}
|
||||
public static final class DatabaseCorruptedError_BothChecksFail extends Error {
|
||||
}
|
||||
public static final class DatabaseCorruptedError_NormalCheckFailsCipherCheckPasses extends Error {
|
||||
}
|
||||
public static final class DatabaseCorruptedError_NormalCheckPassesCipherCheckFails extends Error {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
|
@ -535,4 +536,10 @@ public class Util {
|
|||
|
||||
return primary;
|
||||
}
|
||||
|
||||
public static @NonNull String convertThrowableToString(@NonNull Throwable throwable) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
throwable.printStackTrace(new PrintStream(outputStream));
|
||||
return outputStream.toString();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue