havesource / cordova-plugin-push

Register and receive push notifications
MIT License
150 stars 283 forks source link

High crash rate on Android (Google Play Console): java.lang.Error, java.io.IOException: SERVICE_NOT_AVAILABLE / java.io.IOException: TOO_MANY_REGISTRATIONS #221

Open localhorst opened 1 year ago

localhorst commented 1 year ago

Bug Report

We are using a bugfix commit of this plugin in our Cordova app released for target SDK 31:

"@havesource/cordova-plugin-push": "git+https://github.com/havesource/cordova-plugin-push.git#326057995bf581c5a0c50712cf3a010e01297803"

Link: https://github.com/havesource/cordova-plugin-push/commit/326057995bf581c5a0c50712cf3a010e01297803

We needed the bugfix commit because we experienced background crashes according to #198

Unfortunately, with the current release, we have a relatively high crash rate (0.4- 0.5%) on Android. However, we cannot recreate the crashes. The crashes are spread across a wide variety of devices and Android versions.

The reason seems to be these two error messages: java.io.IOException: SERVICE_NOT_AVAILABLE java.io.IOException: TOO_MANY_REGISTRATIONS. Crashes seem to be related to this Plugin, as PushPlugin.kt is mentioned in the stack trace. According to a review on Google Play, a crash occurs when app is starting (and trying to register with FCM).

Expected Behaviour

No crashes of the app

Actual Behaviour

On some devices and Android versions (8 - 13) the app crashes, probably at startup

Reproduce Scenario (including but not limited to)

Not possible for us so far.

Steps to Reproduce

--

Platform and Version (eg. Android 5.0 or iOS 9.2.1)

Android 10 Android 11 Android 12 Android 13

(Android) Device Vendor (e.g. Samsung, HTC, Sony...)

cordova info Printout

Cordova Packages:

    cli: 11.0.0
        common: 4.0.2
        create: 4.0.0
        lib: 11.0.0
            common: 4.0.2
            fetch: 3.0.1
            serve: 4.0.0

Project Installed Platforms:

    android: 10.1.2
    ios: 6.2.0

Project Installed Plugins:

    @havesource/cordova-plugin-push: 4.0.0-dev.0
    cordova-open-native-settings: 1.5.5
    cordova-plugin-androidx-adapter: 1.1.3
    cordova-plugin-device: 2.1.0
    cordova-plugin-dialogs: 2.0.2
    cordova-plugin-file: 7.0.0
    cordova-plugin-ionic-keyboard: 2.2.0
    cordova-plugin-nativestorage: 2.3.2
    cordova-plugin-splashscreen: 6.0.2
    cordova-plugin-statusbar: 3.0.0
    cordova-support-google-services: 1.4.1

Environment:

    OS: macOS Monterey 12.6 (21G115) (darwin 21.6.0) x64
    Node: v14.15.5
    npm: 6.14.11

android Environment:

    android:
Available Android targets:==============] 100% Fetch remote repository...

ios Environment:

    xcodebuild:
Xcode 14.2
Build version 14C18

Project Setting Files:

    config.xml:
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="20132" id="de.ppw.rsag" ios-CFBundleVersion="46" version="200.2.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="https://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>RSAG-App</name>
    <description>
    RSAG-App
  </description>
    <author email="info@ppw.de" href="http://www.ppw.de/">
    PPW
  </author>
    <content src="index.html" />
    <preference name="phonegap-version" value="cli-8.1.1" />
    <preference name="pgb-builder-version" value="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <preference name="StatusBarOverlaysWebView" value="false" />
        <preference name="SplashMaintainAspectRatio" value="true" />
        <preference name="android-build-tool" value="gradle" />
        <preference name="android-targetSdkVersion" value="31" />
        <preference name="android-minSdkVersion" value="24" />
        <preference name="AndroidPersistentFileLocation" value="Compatibility" />
        <resource-file src="google-services.json" target="/app/google-services.json" />
        <allow-intent href="market:*" />
        <icon density="ldpi" src="res/icon/android/icon-36.png" />
        <icon density="mdpi" src="res/icon/android/icon-48.png" />
        <icon density="hdpi" src="res/icon/android/icon-72.png" />
        <icon density="xhdpi" src="res/icon/android/icon-96.png" />
        <icon density="xxhdpi" src="res/icon/android/icon-144.png" />
        <icon density="xxxhdpi" src="res/icon/android/icon-192.png" />
        <resource-file src="res/icon/android/notification/drawable-mdpi/notification_icon.png" target="app/src/main/res/drawable-mdpi/notification_icon.png" />
        <resource-file src="res/icon/android/notification/drawable-hdpi/notification_icon.png" target="app/src/main/res/drawable-hdpi/notification_icon.png" />
        <resource-file src="res/icon/android/notification/drawable-xhdpi/notification_icon.png" target="app/src/main/res/drawable-xhdpi/notification_icon.png" />
        <resource-file src="res/icon/android/notification/drawable-xxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxhdpi/notification_icon.png" />
        <resource-file src="res/icon/android/notification/drawable-xxxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxxhdpi/notification_icon.png" />
        <resource-file src="res/icon/android/notification/notification_icon.png" target="app/src/main/res/drawable/notification_icon.png" />
        <splash density="land-ldpi" src="res/screen/android/splash-320x200.png" />
        <splash density="land-mdpi" src="res/screen/android/splash-480x320.png" />
        <splash density="land-hdpi" src="res/screen/android/splash-800x480.png" />
        <splash density="land-xhdpi" src="res/screen/android/splash-1280x720.png" />
        <splash density="land-xxhdpi" src="res/screen/android/splash-1600x960.png" />
        <splash density="land-xxxhdpi" src="res/screen/android/splash-1920x1280.png" />
        <splash density="port-ldpi" src="res/screen/android/splash-200x320.png" />
        <splash density="port-mdpi" src="res/screen/android/splash-320x480.png" />
        <splash density="port-hdpi" src="res/screen/android/splash-480x800.png" />
        <splash density="port-xhdpi" src="res/screen/android/splash-720x1280.png" />
        <splash density="port-xxhdpi" src="res/screen/android/splash-960x1600.png" />
        <splash density="port-xxxhdpi" src="res/screen/android/splash-1280x1920.png" />
        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
            <application android:largeHeap="true" />
        </edit-config>
        <config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
            <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
            <meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
        </config-file>
    </platform>
    <platform name="ios">
        <resource-file src="GoogleService-Info.plist" />
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon height="22" src="res/icon/ios/icon-22.png" width="22" />
        <icon height="25" src="res/icon/ios/icon-25.png" width="25" />
        <icon height="29" src="res/icon/ios/icon-29.png" width="29" />
        <icon height="36" src="res/icon/ios/icon-36.png" width="36" />
        <icon height="40" src="res/icon/ios/icon-40.png" width="40" />
        <icon height="44" src="res/icon/ios/icon-44.png" width="44" />
        <icon height="48" src="res/icon/ios/icon-48.png" width="48" />
        <icon height="50" src="res/icon/ios/icon-50.png" width="50" />
        <icon height="55" src="res/icon/ios/icon-55.png" width="55" />
        <icon height="57" src="res/icon/ios/icon-57.png" width="57" />
        <icon height="58" src="res/icon/ios/icon-58.png" width="58" />
        <icon height="60" src="res/icon/ios/icon-60.png" width="60" />
        <icon height="72" src="res/icon/ios/icon-72.png" width="72" />
        <icon height="76" src="res/icon/ios/icon-76.png" width="76" />
        <icon height="80" src="res/icon/ios/icon-80.png" width="80" />
        <icon height="87" src="res/icon/ios/icon-87.png" width="87" />
        <icon height="88" src="res/icon/ios/icon-88.png" width="88" />
        <icon height="100" src="res/icon/ios/icon-100.png" width="100" />
        <icon height="114" src="res/icon/ios/icon-114.png" width="114" />
        <icon height="120" src="res/icon/ios/icon-120.png" width="120" />
        <icon height="144" src="res/icon/ios/icon-144.png" width="144" />
        <icon height="152" src="res/icon/ios/icon-152.png" width="152" />
        <icon height="167" src="res/icon/ios/icon-167.png" width="167" />
        <icon height="172" src="res/icon/ios/icon-172.png" width="172" />
        <icon height="180" src="res/icon/ios/icon-180.png" width="180" />
        <icon height="196" src="res/icon/ios/icon-196.png" width="196" />
        <icon height="216" src="res/icon/ios/icon-216.png" width="216" />
        <icon height="512" src="res/icon/ios/icon-512.png" width="512" />
        <icon height="1024" src="res/icon/ios/icon-1024.png" width="1024" />
        <icon height="1536" src="res/icon/ios/icon-1536.png" width="1536" />
        <splash src="res/screen/ios/Default@2x~iphone~anyany.png" />
        <splash src="res/screen/ios/Default@2x~iphone~comany.png" />
        <splash src="res/screen/ios/Default@2x~iphone~comcom.png" />
        <splash src="res/screen/ios/Default@3x~iphone~anyany.png" />
        <splash src="res/screen/ios/Default@3x~iphone~anycom.png" />
        <splash src="res/screen/ios/Default@3x~iphone~comany.png" />
        <splash src="res/screen/ios/Default@2x~ipad~anyany.png" />
        <splash src="res/screen/ios/Default@2x~ipad~comany.png" />
        <preference name="HideKeyboardFormAccessoryBar" value="false" />
        <preference name="deployment-target" value="13.0" />
        <config-file parent="FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED" target="*-Info.plist">
            <true />
        </config-file>
    </platform>
    <preference name="WKWebViewOnly" value="true" />
    <feature name="CDVWKWebViewEngine">
        <param name="ios-package" value="CDVWKWebViewEngine" />
    </feature>
    <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
    <preference name="orientation" value="portrait" />
    <preference name="BackupWebStorage" value="local" />
    <preference name="SplashScreen" value="screen" />
    <preference name="AutoHideSplashScreen" value="false" />
    <preference name="ShowSplashScreenSpinner" value="false" />
    <preference name="Suppresses3DTouchGesture" value="true" />
    <preference name="iosPersistentFileLocation" value="Library" />
</widget>

    package.json:
--- Start of Cordova JSON Snippet ---
{
  "plugins": {
    "cordova-plugin-ionic-keyboard": {},
    "cordova-plugin-nativestorage": {},
    "@havesource/cordova-plugin-push": {
      "SENDER_ID": "643625173641",
      "FCM_VERSION": "23.+",
      "ANDROIDX_CORE_VERSION": "1.6.+",
      "IOS_FIREBASE_MESSAGING_VERSION": "~> 6.32.2"
    },
    "cordova-open-native-settings": {},
    "cordova-plugin-device": {},
    "cordova-plugin-dialogs": {},
    "cordova-plugin-file": {
      "ANDROIDX_WEBKIT_VERSION": "1.4.0"
    },
    "cordova-plugin-splashscreen": {},
    "cordova-plugin-statusbar": {},
    "cordova-support-google-services": {},
    "cordova-plugin-androidx-adapter": {}
  },
  "platforms": [
    "android",
    "ios"
  ]
}
--- End of Cordova JSON Snippet ---

Sample Push Data Payload

(How can I export / debug a payload, e.g. from an emulator?)

Sample Code that illustrates the problem

--

Logs taken while reproducing problem

From Google Play Console:

Stacktrace 1:

Exception java.lang.Error: java.util.concurrent.ExecutionException: java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: SERVICE_NOT_AVAILABLE
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1173)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
  at java.lang.Thread.run (Thread.java:920)
Caused by java.util.concurrent.ExecutionException: java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: SERVICE_NOT_AVAILABLE
  at com.google.android.gms.tasks.Tasks.zza (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.Tasks.await (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.adobe.phonegap.push.PushPlugin.executeActionInitialize$lambda-8 (PushPlugin.kt:465)
  at com.adobe.phonegap.push.PushPlugin.lambda$ohS9Ls90r5WAZnI3N99GgMOBsaE
  at com.adobe.phonegap.push.-$$Lambda$PushPlugin$ohS9Ls90r5WAZnI3N99GgMOBsaE.run
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
Caused by java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: SERVICE_NOT_AVAILABLE
  at com.google.firebase.messaging.FirebaseMessaging.blockingGetToken (FirebaseMessaging.java:628)
  at com.google.firebase.messaging.FirebaseMessaging.lambda$getToken$4$FirebaseMessaging (FirebaseMessaging.java:393)
  at com.google.firebase.messaging.-$$Lambda$FirebaseMessaging$m5Uvt0n8P9zrx-ecASLTQKzoABQ.run
  at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:462)
  at java.util.concurrent.FutureTask.run (FutureTask.java:266)
  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run (ScheduledThreadPoolExecutor.java:301)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
  at com.google.android.gms.common.util.concurrent.zza.run (com.google.android.gms:play-services-basement@@18.1.0:2)
Caused by java.util.concurrent.ExecutionException: java.io.IOException: SERVICE_NOT_AVAILABLE
  at com.google.android.gms.tasks.Tasks.zza (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.Tasks.await (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.google.firebase.messaging.FirebaseMessaging.blockingGetToken (FirebaseMessaging.java:626)
Caused by java.io.IOException: SERVICE_NOT_AVAILABLE
  at com.google.firebase.messaging.GmsRpc.handleResponse (GmsRpc.java:309)
  at com.google.firebase.messaging.GmsRpc.lambda$extractResponseWhenComplete$0$GmsRpc (GmsRpc.java:320)
  at com.google.firebase.messaging.-$$Lambda$GmsRpc$cZg7VRs3aHaJlHVdosXKlJfYwHY.then
  at com.google.android.gms.tasks.zzc.run (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.firebase.messaging.-$$Lambda$PNiE7SuEFxRjAZH7pJpZIFOFjWg.execute
  at com.google.android.gms.tasks.zzd.zzd (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.tasks.zzr.zzb (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.zzw.zzb (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.android.gms.tasks.zzc.run (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.google.android.gms.cloudmessaging.zzz.execute
  at com.google.android.gms.tasks.zzd.zzd (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.tasks.zzr.zzb (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.zzw.zzb (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.android.gms.tasks.TaskCompletionSource.setResult (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.cloudmessaging.zzp.zzd (com.google.android.gms:play-services-cloud-messaging@@17.0.0:3)
  at com.google.android.gms.cloudmessaging.zzr.zza (com.google.android.gms:play-services-cloud-messaging@@17.0.0:2)
  at com.google.android.gms.cloudmessaging.zzf.handleMessage (com.google.android.gms:play-services-cloud-messaging@@17.0.0:14)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8751)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)

Stacktrace 2:

Exception java.lang.Error:
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1173)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
  at java.lang.Thread.run (Thread.java:920)
Caused by java.util.concurrent.ExecutionException: java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: TOO_MANY_REGISTRATIONS
  at com.google.android.gms.tasks.Tasks.zza (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.Tasks.await (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.adobe.phonegap.push.PushPlugin.executeActionInitialize$lambda-8 (PushPlugin.kt:465)
  at com.adobe.phonegap.push.PushPlugin.lambda$ohS9Ls90r5WAZnI3N99GgMOBsaE
  at com.adobe.phonegap.push.-$$Lambda$PushPlugin$ohS9Ls90r5WAZnI3N99GgMOBsaE.run
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
Caused by java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: TOO_MANY_REGISTRATIONS
  at com.google.firebase.messaging.FirebaseMessaging.blockingGetToken (FirebaseMessaging.java:628)
  at com.google.firebase.messaging.FirebaseMessaging.lambda$getToken$4$FirebaseMessaging (FirebaseMessaging.java:393)
  at com.google.firebase.messaging.-$$Lambda$FirebaseMessaging$m5Uvt0n8P9zrx-ecASLTQKzoABQ.run
  at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:462)
  at java.util.concurrent.FutureTask.run (FutureTask.java:266)
  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run (ScheduledThreadPoolExecutor.java:301)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
  at com.google.android.gms.common.util.concurrent.zza.run (com.google.android.gms:play-services-basement@@18.1.0:2)
Caused by java.util.concurrent.ExecutionException: java.io.IOException: TOO_MANY_REGISTRATIONS
  at com.google.android.gms.tasks.Tasks.zza (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.Tasks.await (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.google.firebase.messaging.FirebaseMessaging.blockingGetToken (FirebaseMessaging.java:626)
Caused by java.io.IOException: TOO_MANY_REGISTRATIONS
  at com.google.firebase.messaging.GmsRpc.handleResponse (GmsRpc.java:309)
  at com.google.firebase.messaging.GmsRpc.lambda$extractResponseWhenComplete$0$GmsRpc (GmsRpc.java:320)
  at com.google.firebase.messaging.-$$Lambda$GmsRpc$cZg7VRs3aHaJlHVdosXKlJfYwHY.then
  at com.google.android.gms.tasks.zzc.run (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.firebase.messaging.-$$Lambda$PNiE7SuEFxRjAZH7pJpZIFOFjWg.execute
  at com.google.android.gms.tasks.zzd.zzd (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.tasks.zzr.zzb (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.zzw.zzb (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.android.gms.tasks.zzc.run (com.google.android.gms:play-services-tasks@@18.0.1:8)
  at com.google.android.gms.cloudmessaging.zzz.execute
  at com.google.android.gms.tasks.zzd.zzd (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.tasks.zzr.zzb (com.google.android.gms:play-services-tasks@@18.0.1:5)
  at com.google.android.gms.tasks.zzw.zzb (com.google.android.gms:play-services-tasks@@18.0.1:3)
  at com.google.android.gms.tasks.TaskCompletionSource.setResult (com.google.android.gms:play-services-tasks@@18.0.1:1)
  at com.google.android.gms.cloudmessaging.zzp.zzd (com.google.android.gms:play-services-cloud-messaging@@17.0.0:3)
  at com.google.android.gms.cloudmessaging.zzr.zza (com.google.android.gms:play-services-cloud-messaging@@17.0.0:2)
  at com.google.android.gms.cloudmessaging.zzf.handleMessage (com.google.android.gms:play-services-cloud-messaging@@17.0.0:14)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8751)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1135)
sithwarrior commented 1 year ago

Seeing the exact same issue, with approx the same crash rate

localhorst commented 1 year ago

Is there any update on this?

For us, this bug makes using this plugin unsustainable. We have decided to switch our app architecture to Capacitor because we don't know if the future of Cordova as a whole is stable.

sithwarrior commented 1 year ago

Apparently there can be issues, where the token isn't generated yet by the FCM service, and this can creates crashes, in the token get method.

Its described here: https://stackoverflow.com/questions/50208426/android-fcm-java-io-ioexception-service-not-available-error-on-some-devices/53919064

its handled in the PushPlugin.kt file

        val token = try {
          try {
            Tasks.await(FirebaseMessaging.getInstance().token)
          } catch (e: ExecutionException) {
            throw e.cause ?: e
          }
        } catch (e: IllegalStateException) {
          Log.e(TAG, formatLogMessage("Firebase Token Exception ${e.message}"))
          null
        } catch (e: ExecutionException) {
          Log.e(TAG, formatLogMessage("Firebase Token Exception ${e.message}"))
          null
        } catch (e: InterruptedException) {
          Log.e(TAG, formatLogMessage("Firebase Token Exception ${e.message}"))
          null
        }

But this seems to be a different exception, and is causing crashes in production