Ignore errors that are likely due to filesystem corruption.

There is a specific POSIX error "EIO" which seems to be the "general
purpose we don't know what went wrong but its probably bad" exception.
Our investigations in #855 resulted in the conclusion that it is likely
due to some sort of filesystem corruption or something like that.

Either way, it is annoying many people, so we need to prevent it or
ignore it, rather than prompting the user to submit a bug report.
After much investigation it was unable to be reproduced other than by
one of the original bug reporters. As such, this change ignores it.

Unfortunately Java `IOException`s don't have an API for getting the
errno of a POSIX IO error. Thus, this change results to parsing the
exception message instead :(

Fixes #855.
Refs !440
This commit is contained in:
Peter Serwylo 2017-04-01 15:46:09 +02:00 committed by Hans-Christoph Steiner
parent 4eb37b0d33
commit aab60aec4e
2 changed files with 40 additions and 6 deletions

View File

@ -408,13 +408,29 @@ public final class Utils {
byte[] mdbytes = md.digest();
return toHexString(mdbytes).toLowerCase(Locale.ENGLISH);
} catch (IOException | NoSuchAlgorithmException e) {
} catch (IOException e) {
// The annoyance (potentially) caused by miscellaneous filesystem corruption results in
// F-Droid constantly popping up crash reports when F-Droid isn't even open. As such this
// exception-message-parsing-and-throwing-a-new-ignorable-exception-hackery is probably
// warranted. See https://www.gitlab.com/fdroid/fdroidclient/issues/855 for more detail.
if (e.getMessage().contains("read failed: EIO (I/O error)")) {
throw new PotentialFilesystemCorruptionException(e);
}
throw new IllegalArgumentException(e);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
} finally {
closeQuietly(fis);
}
}
public static class PotentialFilesystemCorruptionException extends IllegalArgumentException {
public PotentialFilesystemCorruptionException(IOException e) {
super(e);
}
}
/**
* Computes the base 16 representation of the byte array argument.
*

View File

@ -8,13 +8,19 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import org.acra.ACRA;
import org.fdroid.fdroid.Hasher;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import java.io.File;
import java.io.FilenameFilter;
@ -23,10 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
/**
* Handles all updates to {@link InstalledAppProvider}, whether checking the contents
* versus what Android says is installed, or processing {@link Intent}s that come
@ -197,6 +199,22 @@ public class InstalledAppProviderService extends IntentService {
String hashType = "sha256";
String hash = Utils.getBinaryHash(apk, hashType);
insertAppIntoDb(this, packageInfo, hashType, hash);
} catch (final Utils.PotentialFilesystemCorruptionException e) {
Log.e(TAG, "Encountered potential filesystem corruption, or other unknown " +
"problem when calculating hash of " + apk.getAbsolutePath() + ". " +
"It is unlikely F-Droid can do anything about this, and this " +
"likely happened in the background. As such, we will continue without " +
"interrupting the user by asking them to send a crash report.");
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Context context = getApplicationContext();
Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
return;
} catch (IllegalArgumentException e) {
Utils.debugLog(TAG, e.getMessage());
ACRA.getErrorReporter().handleException(e, false);