Add Java example of fatal error handler.
This commit is contained in:
parent
9a58bc03ab
commit
1dec0e203c
@ -17,6 +17,7 @@ import java.util.NavigableSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -606,9 +607,80 @@ public final class Example {
|
||||
@Override
|
||||
public void onLogMessage(int verbosityLevel, String message) {
|
||||
if (verbosityLevel == 0) {
|
||||
// a fatal error, the app will crash right after the function returns
|
||||
onFatalError(message);
|
||||
return;
|
||||
}
|
||||
System.err.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void onFatalError(String errorMessage) {
|
||||
final class ThrowError implements Runnable {
|
||||
private final String errorMessage;
|
||||
private final AtomicLong errorThrowTime;
|
||||
|
||||
private ThrowError(String errorMessage, AtomicLong errorThrowTime) {
|
||||
this.errorMessage = errorMessage;
|
||||
this.errorThrowTime = errorThrowTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isDatabaseBrokenError(errorMessage) || isDiskFullError(errorMessage) || isDiskError(errorMessage)) {
|
||||
processExternalError();
|
||||
return;
|
||||
}
|
||||
|
||||
errorThrowTime.set(System.currentTimeMillis());
|
||||
throw new ClientError("TDLib fatal error: " + errorMessage);
|
||||
}
|
||||
|
||||
private void processExternalError() {
|
||||
errorThrowTime.set(System.currentTimeMillis());
|
||||
throw new ExternalClientError("Fatal error: " + errorMessage);
|
||||
}
|
||||
|
||||
private static final class ClientError extends Error {
|
||||
private ClientError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ExternalClientError extends Error {
|
||||
public ExternalClientError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDatabaseBrokenError(String message) {
|
||||
return message.contains("Wrong key or database is corrupted") ||
|
||||
message.contains("SQL logic error or missing database") ||
|
||||
message.contains("database disk image is malformed") ||
|
||||
message.contains("file is encrypted or is not a database") ||
|
||||
message.contains("unsupported file format") ||
|
||||
message.contains("Database was corrupted and deleted during execution and can't be recreated");
|
||||
}
|
||||
|
||||
private static boolean isDiskFullError(String message) {
|
||||
return message.contains("PosixError : No space left on device") ||
|
||||
message.contains("database or disk is full");
|
||||
}
|
||||
|
||||
private static boolean isDiskError(String message) {
|
||||
return message.contains("I/O error") || message.contains("Structure needs cleaning");
|
||||
}
|
||||
}
|
||||
|
||||
final AtomicLong errorThrowTime = new AtomicLong(Long.MAX_VALUE);
|
||||
new Thread(new ThrowError(errorMessage, errorThrowTime), "TDLib fatal error thread").start();
|
||||
|
||||
// wait at least 10 seconds after the error is thrown
|
||||
while (errorThrowTime.get() >= System.currentTimeMillis() - 10000) {
|
||||
try {
|
||||
Thread.sleep(1000 /* milliseconds */);
|
||||
} catch (InterruptedException ignore) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user