Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing webview provider crash on Android #29089

Closed
wants to merge 1 commit into from
Closed

Fix missing webview provider crash on Android #29089

wants to merge 1 commit into from

Conversation

Almouro
Copy link
Contributor

@Almouro Almouro commented Jun 8, 2020

Summary

We upgraded to RN 0.62.2 on our latest release and started to see again the "Failed to load WebView provider: No WebView installed" (see below for Crashlytics screenshot)

image

This crash had been fixed by #24533 but #26189 (added in 0.62) reverted the fix

Indeed the exception raised in Crashlytics is actually a AndroidRuntimeException and MissingWebViewPackageException is only part of the message.

For instance, in the screenshot above, the exception message is android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed

Now these crashes are quite tricky to reproduce, so to be on the safe side, I'm filtering out all exceptions containing WebView as suggested by @thorbenprimke on the original fix.

If my reasoning is correct, it should fix @siddhantsoni 's issue as well, since WebView is included in MissingWebViewPackageException
But following that reasoning, I am not sure #26189 fixed @siddhantsoni 's issue, so @siddhantsoni if you could check that this PR also fixes your issue, that would be great!

Changelog

[Android] [Fixed] - Fix missing WebView provider crash in ForwardingCookieHandler

Test Plan

I created a version of react native with this patch applied

"react-native": "almouro/react-native#release/062-2-fix-missing-webview-provider"

Before the fix ~0.1% of our users were impacted on Android, no new crashes have occurred after the update.

This is putting back what was already in place and working for us, but making the check wider to catch more errors.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 8, 2020
@Almouro Almouro changed the title Fix missing webview provider crash Fix missing webview provider crash on Android Jun 8, 2020
@react-native-bot react-native-bot added Bug Platform: Android Android applications. labels Jun 8, 2020
@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 6,760,639 -75
android hermes armeabi-v7a 6,423,412 -63
android hermes x86 7,147,075 -68
android hermes x86_64 7,037,098 -61
android jsc arm64-v8a 8,934,212 -75
android jsc armeabi-v7a 8,589,372 -69
android jsc x86 8,763,772 -54
android jsc x86_64 9,339,416 -75

Base commit: a50fa55

@analysis-bot
Copy link

analysis-bot commented Jun 8, 2020

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: a50fa55

@jocoders
Copy link

Any news how to decide this error?

@Almouro
Copy link
Contributor Author

Almouro commented Aug 26, 2020

@jocoders Not sure 😅

@cpojer @thorbenprimke you guys reviewed the previous PR about the same subject, maybe you can help here? 🙏

.getClass()
.getCanonicalName()
.equals("android.webkit.WebViewFactory.MissingWebViewPackageException")) {
if (message != null && message.contains("WebView")) {
Copy link
Contributor

@thorbenprimke thorbenprimke Aug 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the right fix to catch both the original case (from my fix) and the cases by @siddhantsoni, it would be combine both.

if ((message != null && message.contains("No WebView installed")) || 
    exception	
                .getClass()	
                .getCanonicalName()	
                .equals("android.webkit.WebViewFactory.MissingWebViewPackageException")
) {

The reason for this is that if you look at the exceptions listed on #26189, the message does not always contain WebView. Looking back at the crashes listed on #24533, they were also AndroidRuntimeExceptions like the ones that you (@Almouro) are seeing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, your fix catch both cases.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my case the exception message is android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed

So maybe we can check for the message to contain MissingWebViewPackageException and that would do it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Almouro – What do you think about @capezzbr's suggestion? Alternatively would the following sufficiently capture all cases?

exception.getClass().getCanonicalName().contains("MissingWebViewPackageException")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Almouro, would you be able to take a look at the above comments?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sota000, I created a new PR with the changes requested.

PR: RodolfoGS#1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey. It seems that on some devices that crash comes out as a runtime crash "android.util.AndroidRuntimeException" and the check fails. I can reproduce it by disabling the webview on the device. Should we also add it to the check? @RodolfoGS @yungsters @sota000

@9Hyeonwoo
Copy link

9Hyeonwoo commented Feb 15, 2021

Hi guys. @jocoders @Almouro
I found a way to reproduce this exception.
After Disable Android System WebView system app, you can get AndroidRuntimeException exception with MissingWebViewPackageException message.

Could you check the case and merge this PR?

@jocoders
Copy link

jocoders commented Mar 19, 2021

Hi guys. @jocoders @Almouro
I found a way to reproduce this exception.
After Disable Android System WebView system app, you can get AndroidRuntimeException exception with MissingWebViewPackageException message.

Could you check the case and merge this PR?

Dear 9Hyeonwoo! I disabled all browsers on the test phone and tried to open some links from my app, but the app did not crashed and no errors. Your case of the error's appearance has not confirmed on my app. Any new ideas how to reproduce this error?

@spsaucier-bakkt
Copy link

We're getting this error for a few users of our app as well, so this fix would be very welcome.

@RodolfoGS
Copy link
Contributor

RodolfoGS commented Mar 25, 2021

@jocoders I could reproduce the crash disabling Android System WebView as mentioned @9Hyeonwoo.

To do that I followed this steps:

  1. Go to Settings
  2. Application manager (or apps)
  3. Downloaded / all apps
  4. Search for Android System WebView and just disable it.

After of that, my crash when it starts.


@Almouro Do you know how I could create a patch (using patch-package for example) to apply your changes to my project? Since the ForwardingCookieHandler.java is a read-only file.

I can edit the file located in:

node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java

But when I navigate with Android Studio that file is located in:

node_modules/react-native/android/com/facebook/react/react-native/0.63.4/react-native-0.63.4-sources.jar!/com/facebook/react/modules/network/ForwardingCookieHandler.java

Thanks a lot!

.getClass()
.getCanonicalName()
.equals("android.webkit.WebViewFactory.MissingWebViewPackageException")) {
if (message != null && message.contains("WebView")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, your fix catch both cases.

@RodolfoGS
Copy link
Contributor

Anyone know someone from the react-native team to merge this PR? It's a super simple PR that fix an easy reproducible crash and are opened for about 1 year ago ¯_(ツ)_/¯

@aguglie
Copy link

aguglie commented May 8, 2021

Hello, same problem on RN 0.64.0; waiting for the merge to be approved 😊

@mishsom
Copy link

mishsom commented Jun 22, 2021

Facing the same issue in our production application, is there a way we can handle this from user code?

@sota000 sota000 self-assigned this Aug 30, 2021
@facebook-github-bot
Copy link
Contributor

@sota000 has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@sota000
Copy link
Contributor

sota000 commented Aug 30, 2021

I imported the diff for internal review. Since there is a comment about improving the check, please feel free to create a new PR or update this PR to include the suggestions.

@sota000 sota000 self-requested a review September 3, 2021 00:37
Copy link
Contributor

@sota000 sota000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for taking the time to review. Please address the comments made inline, and I will reimport the PR.

.getClass()
.getCanonicalName()
.equals("android.webkit.WebViewFactory.MissingWebViewPackageException")) {
if (message != null && message.contains("WebView")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Almouro, would you be able to take a look at the above comments?

@sota000
Copy link
Contributor

sota000 commented Sep 7, 2021

@RodolfoGS, can you please create the pull request to the React Native repo instead of your fork? We will import and merge the version as this PR has been stale for a while. Thanks!

@RodolfoGS
Copy link
Contributor

@sota000 You are right, my fault, sorry for that. I created a new one #32165

@sota000
Copy link
Contributor

sota000 commented Sep 9, 2021

I am going to close this PR and will work on merging #32165. Thanks @RodolfoGS for taking it over as well as @Almouro and others for the initial contribution!

@sota000 sota000 closed this Sep 9, 2021
facebook-github-bot pushed a commit that referenced this pull request Sep 9, 2021
Summary:
I applied the changes requested in this PR: #29089

We upgraded to RN 0.62.2 on our latest release and started to see again the "Failed to load WebView provider: No WebView installed" (see below for Crashlytics screenshot)

![image](https://user-images.githubusercontent.com/870365/131935283-033fbd44-5a3b-49b0-bd25-3d6733f22040.png)

This crash had been fixed by #24533 but #26189 (added in 0.62) reverted the fix

Indeed the exception raised in Crashlytics is actually a `AndroidRuntimeException` and `MissingWebViewPackageException` is only part of the message.

For instance, in the screenshot above, the exception message is `android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed`

Now these crashes are quite tricky to reproduce, so to be on the safe side, I'm filtering out all exceptions containing `WebView` as suggested by thorbenprimke on the original fix.

If my reasoning is correct, it should fix siddhantsoni 's issue as well, since `WebView` is included in `MissingWebViewPackageException`
But following that reasoning, I am not sure #26189 fixed siddhantsoni 's issue, so siddhantsoni if you could check that this PR also fixes your issue, that would be great!

## Changelog

[Android] [Fixed] - Fix missing WebView provider crash in ForwardingCookieHandler

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

Pull Request resolved: #32165

Test Plan:
I created a version of react native with this patch applied

```
"react-native": "almouro/react-native#release/062-2-fix-missing-webview-provider"
```

Before the fix ~0.1% of our users were impacted on Android, no new crashes have occurred after the update.

This is putting back what was already in place and working for us, but making the check wider to catch more errors.

Reviewed By: lunaleaps

Differential Revision: D30847404

Pulled By: sota000

fbshipit-source-id: fe3b5fa2c9ebde5bedd17a9d6394a52ccdbdf0d0
@Almouro
Copy link
Contributor Author

Almouro commented Sep 16, 2021

Great news that this is fixed! 🎉 Thanks @RodolfoGS for taking over and @sota000 for getting it merged!

@NoRamadon
Copy link

I still can reproduce this issue after update to 0.67.0-rc.3.

facebook-github-bot pushed a commit that referenced this pull request Feb 15, 2022
Summary:
The check implemented in PR #29089 is flawed as the exception class name and message depends on the OS version as well as the OEM. In OxygenOS running android 11, it comes out as RuntimeException and the check fails and hence the crash occurs again. But on observing closely, its clear that the exception message is consistent across OEMs with similar strings appearing in them that have been included in the if check.
Hence there is a simple fix to this issue, by checking the message instead of the exception class.

Here is the snippet:

```
private Nullable CookieManager getCookieManager() {
    if (mCookieManager == null) {
      possiblyWorkaroundSyncManager(mContext);
      try {
        mCookieManager = CookieManager.getInstance();
      } catch (IllegalArgumentException ex) {
        // https://bugs.chromium.org/p/chromium/issues/detail?id=559720
        return null;
      } catch (Exception exception) {
        String message = exception.getMessage();
        // We cannot catch MissingWebViewPackageException as it is in a private / system API
        // class. This validates the exception's message to ensure we are only handling this
        // specific exception.
        // The exception class doesn't always contain the correct name as it depends on the OEM
        // and OS version. It is better to check the message for clues regarding the exception
        // as that is somewhat consistent across OEMs.
        // For instance, the Exception thrown on OxygenOS 11 is a RuntimeException but the message contains the required strings.
        // https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/webkit/WebViewFactory.java#348
       if (exception.getClass().getCanonicalName().contains("MissingWebViewPackageException") ||
            (message!=null && (message.contains("WebView provider") ||
               message.contains("No WebView installed")))){
            return null;
        } else {
          throw exception;
        }
      }
    }

    return mCookieManager;
  }
```

## Changelog

[General] [Added] - A fail proof check to catch any crash involving webview:
if (exception.getClass().getCanonicalName().contains("MissingWebViewPackageException") || (message!=null && (message.contains("WebView provider") || message.contains("No WebView installed"))))
[General] [Removed] - Flawed check to catch WebViewProvider crash:
if (message != null && exception.getClass().getCanonicalName().contains("MissingWebViewPackageException"))

Pull Request resolved: #33088

Test Plan:
This code has been tested rigorously on OnePlus Nord CE 5G (Oxygen OS 11.0) and Realme X (Realme UI 2.0) both running on Android 11 and reproducing the crash on a hybrid (Native android + ReactNative) app that showed this crash in production being dependent on WebViews. I have implemented an entire patched fork of 0.67.2 to fix this issue in our app.

How to test:

Launch any app that has a webview.
Go to settings->apps->Android System Webview -> disable.
Resume/Restart the app.

In this fix:
Open a webview and notice that the app will not crash.

In current version:
App crashes on startup as the exception escapes the catch block.
Even if it survives startup (did on Realme X), it will crash once you try to open a webview.

Reviewed By: rh389

Differential Revision: D34240097

Pulled By: cortinico

fbshipit-source-id: 0f1f9a3b078c0ad3074c7841392892cb70b427eb
@HugoGresse
Copy link

could it be possible there was a regression regarding this issue?
Having the issue for one month:
image
starting version 0.68.0

@RodolfoGS
Copy link
Contributor

@HugoGresse seems that was merged on 0.70.1 -> https://github.com/facebook/react-native/releases/tag/v0.70.1

Avoid crash in ForwardingCookieHandler if webview is disabled (5451cd48bd by @Pajn)

Saadnajmi pushed a commit to Saadnajmi/react-native-macos that referenced this pull request Jan 15, 2023
…book#33088)

Summary:
The check implemented in PR facebook#29089 is flawed as the exception class name and message depends on the OS version as well as the OEM. In OxygenOS running android 11, it comes out as RuntimeException and the check fails and hence the crash occurs again. But on observing closely, its clear that the exception message is consistent across OEMs with similar strings appearing in them that have been included in the if check.
Hence there is a simple fix to this issue, by checking the message instead of the exception class.

Here is the snippet:

```
private Nullable CookieManager getCookieManager() {
    if (mCookieManager == null) {
      possiblyWorkaroundSyncManager(mContext);
      try {
        mCookieManager = CookieManager.getInstance();
      } catch (IllegalArgumentException ex) {
        // https://bugs.chromium.org/p/chromium/issues/detail?id=559720
        return null;
      } catch (Exception exception) {
        String message = exception.getMessage();
        // We cannot catch MissingWebViewPackageException as it is in a private / system API
        // class. This validates the exception's message to ensure we are only handling this
        // specific exception.
        // The exception class doesn't always contain the correct name as it depends on the OEM
        // and OS version. It is better to check the message for clues regarding the exception
        // as that is somewhat consistent across OEMs.
        // For instance, the Exception thrown on OxygenOS 11 is a RuntimeException but the message contains the required strings.
        // https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/webkit/WebViewFactory.java#348
       if (exception.getClass().getCanonicalName().contains("MissingWebViewPackageException") ||
            (message!=null && (message.contains("WebView provider") ||
               message.contains("No WebView installed")))){
            return null;
        } else {
          throw exception;
        }
      }
    }

    return mCookieManager;
  }
```

## Changelog

[General] [Added] - A fail proof check to catch any crash involving webview:
if (exception.getClass().getCanonicalName().contains("MissingWebViewPackageException") || (message!=null && (message.contains("WebView provider") || message.contains("No WebView installed"))))
[General] [Removed] - Flawed check to catch WebViewProvider crash:
if (message != null && exception.getClass().getCanonicalName().contains("MissingWebViewPackageException"))

Pull Request resolved: facebook#33088

Test Plan:
This code has been tested rigorously on OnePlus Nord CE 5G (Oxygen OS 11.0) and Realme X (Realme UI 2.0) both running on Android 11 and reproducing the crash on a hybrid (Native android + ReactNative) app that showed this crash in production being dependent on WebViews. I have implemented an entire patched fork of 0.67.2 to fix this issue in our app.

How to test:

Launch any app that has a webview.
Go to settings->apps->Android System Webview -> disable.
Resume/Restart the app.

In this fix:
Open a webview and notice that the app will not crash.

In current version:
App crashes on startup as the exception escapes the catch block.
Even if it survives startup (did on Realme X), it will crash once you try to open a webview.

Reviewed By: rh389

Differential Revision: D34240097

Pulled By: cortinico

fbshipit-source-id: 0f1f9a3b078c0ad3074c7841392892cb70b427eb
@iphonic
Copy link

iphonic commented Mar 26, 2024

This still giving error, log from Crashlytics using React Native v0.71.11

Fatal Exception: android.util.AndroidRuntimeException android.util.AndroidRuntimeException: android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed

Fatal Exception: android.util.AndroidRuntimeException: android.util.AndroidRuntimeException: android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed
       at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:382)
       at android.webkit.CookieManager.getInstance(CookieManager.java:50)
       at com.facebook.react.modules.network.ForwardingCookieHandler.getCookieManager(ForwardingCookieHandler.java:10)
       at com.facebook.react.modules.network.ForwardingCookieHandler.get(ForwardingCookieHandler.java)
       at okhttp3.JavaNetCookieJar.loadForRequest(JavaNetCookieJar.java:15)
       at com.facebook.react.modules.network.ReactCookieJarContainer.loadForRequest(ReactCookieJarContainer.java:4)
       at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:130)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:166)
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:34)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:166)
       at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.java:113)
       at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.java:51)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
       at java.lang.Thread.run(Thread.java:1012)

More details

Device
Brand:Samsung
Model:Galaxy A32
Orientation:Portrait
RAM free: 1.89 GB
Disk free: 77.11 GB

Operating system
Version:Android 13
Orientation:Portrait
Rooted:No

Crash
Date:23 Mar 2024, 19:31:02

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Platform: Android Android applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.