5

Due to a bug in Android 4.3, my app crashes when trying to load certain webpages in webview

The stack trace is like this:

09-16 14:16:48.221: E/AndroidRuntime(22487): FATAL EXCEPTION: WebViewCoreThread
09-16 14:16:48.221: E/AndroidRuntime(22487): java.lang.StringIndexOutOfBoundsException: length=0; index=-1
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.AbstractStringBuilder.indexAndLength(AbstractStringBuilder.java:212)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:206)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.StringBuffer.charAt(StringBuffer.java:346)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509NameTokenizer.nextToken(X509NameTokenizer.java:78)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:719)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:655)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at com.android.org.bouncycastle.asn1.x509.X509Name.<init>(X509Name.java:593)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate$DName.<init>(SslCertificate.java:379)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate.<init>(SslCertificate.java:189)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.net.http.SslCertificate.<init>(SslCertificate.java:178)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.BrowserFrame.setCertificate(BrowserFrame.java:1206)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.JWebCoreJavaBridge.nativeServiceFuncPtrQueue(Native Method)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.JWebCoreJavaBridge.handleMessage(JWebCoreJavaBridge.java:113)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.os.Looper.loop(Looper.java:137)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:814)
09-16 14:16:48.221: E/AndroidRuntime(22487):    at java.lang.Thread.run(Thread.java:841)

In my webview I have onReceivedSslError, and onReceivedError methods overridden but none of them is able to catch this exception.

try{
    webview.postUrl(url, EncodingUtils.getBytes(data, "BASE64"));
}
catch(Exception e){
    System.out.println("Caught the exception!");
}

surrounding the call to postUrl with a try/catch block (as above) also doesn't catch the exception.

Is there any way to catch this exception so that I can display a meaningful error message instead of letting the app crash?

SBerg413
  • 14,515
  • 6
  • 62
  • 88
Atul Goyal
  • 3,511
  • 5
  • 39
  • 59
  • @ClaireG : as you can see, the exception is not related to any code the SO wrote, but rather to a known issue with the ssl handling of webviews. – njzk2 Sep 16 '13 at 09:07
  • duplicate question http://stackoverflow.com/questions/18130047/android-webview-crash-4-3 – Hariharan Sep 16 '13 at 09:09
  • @Tamilan: In this question I am exploring possibility of catching such an exception. I'm not asking why the error is happening. Hope it helps. – Atul Goyal Sep 16 '13 at 09:10

2 Answers2

8

You may have to try setting up a global uncaught exception handler. You do this by extending Application and defining the uncaught exception handler within there. It would look something like this:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, final Throwable ex) {
                // Custom code here to handle the error.
            }
        });
    }

}

Just make sure you point to your custom Application class in your Manifest.
Give that a shot. hope it helps.

SBerg413
  • 14,515
  • 6
  • 62
  • 88
  • 4
    +1 - This is a start and also make sure you catch this exception alone and pass rest of the exceptions to OS. – AjOnFire Oct 22 '13 at 15:04
  • 1
    Makes sense, I haven't been able to check it out yet but have to award you the bounty as the time is running out. I'll test it and update here! One thing which still remains unexplained is why can't the error be caught at activity level but can be, at the app level (assuming this actually works). – Atul Goyal Oct 25 '13 at 14:56
1

Regarding the question of why the exception could not be caught at activity level, the reason is that the exception occurred in a new thread, not in the try block.

The setDefaultUncaughtExceptionHandler sometimes does not work because the default handler could be overwritten by the later code.

And you are not able to recover from the exception in the UncaughtExceptionHandler. All you can do is to log it and kill the process itself.

Jared Tsai
  • 51
  • 7