dev-plugins icon indicating copy to clipboard operation
dev-plugins copied to clipboard

App crashes on splash screen

Open alioguzhan opened this issue 1 year ago • 29 comments
trafficstars

Thanks for the great work for Expo 50.

I enabled the DevTools plugin for react-navigation in my index.tsx file:

image

The app works fine with the dev server locally. But When I build it and try the development build (apk file on my device or emulator), the app hangs at the Splash screen. And this is the adb log from the console:

01-20 14:00:03.693  4767  4812 I cr_LibraryLoader: Successfully loaded native library
01-20 14:00:03.693  4767  4812 I cr_CachingUmaRecorder: Flushed 8 samples from 8 histograms.
01-20 14:00:03.699  4767  4811 E ReactNativeJS: Error: Failed to setup client from useDevToolsPluginClient: [object Object]
01-20 14:00:03.699  4767  4811 E ReactNativeJS:
01-20 14:00:03.699  4767  4811 E ReactNativeJS: This error is located at:
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in Index
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in RCTView
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in Unknown
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in RCTView
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in Unknown
01-20 14:00:03.699  4767  4811 E ReactNativeJS:     in AppContainer, js engine: hermes
01-20 14:00:03.701   402   402 I RanchuHwc: validateDisplay: layer 66 CompositionType 1, fallback to client
01-20 14:00:03.701   402   402 I RanchuHwc: validateDisplay: layer 65 CompositionType 1, fallback to client
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: Error: Failed to setup client from useDevToolsPluginClient: [object Object]
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: This error is located at:
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in Index
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in RCTView
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in Unknown
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in RCTView
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in Unknown
01-20 14:00:03.702  4767  4812 E unknown:ReactNative:     in AppContainer, js engine: hermes, stack:
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: ?anon_0_@1:3334106
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: asyncGeneratorStep@1:148149
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: _throw@1:148451
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: tryCallOne@53:15
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: anonymous@139:26
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: anonymous@1:321582
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: _callTimer@1:320581
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: _callReactNativeMicrotasksPass@1:320725
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: callReactNativeMicrotasks@1:322659
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: __callReactNativeMicrotasks@1:163417
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: anonymous@1:162552
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: __guard@1:163291
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: flushedQueue@1:162463
01-20 14:00:03.702  4767  4812 E unknown:ReactNative: callFunctionReturnFlushedQueue@1:162319

Versions

expo: 50.0.2 react-navigation/native: 6.1.9 react-navigation/stack: 6.3.20 react-navigation/drawer: 6.6.6

Not sure if this is related to this plugin or react-router. Thanks.

alioguzhan avatar Jan 20 '24 11:01 alioguzhan

sorry i was not doing good for the error message, could you help to troubleshoot at your node_modules/expo/build/devtools/index.js to dump the error and its stack

        async function setup() {
            try {
                const client = await getDevToolsPluginClientAsync(pluginName);
                setClient(client);
            }
            catch (e) {
                setError(new Error('Failed to setup client from useDevToolsPluginClient: ' + e.toString()));
            }
        }

in the catch section, trying to console.log(e.stack) or console.log(e)

Kudo avatar Jan 20 '24 13:01 Kudo

Will do it when I get home @Kudo,

In addition to that, Should we replace the e.toString() with JSON.stringify(e) ? I can create a PR for that. toString fails when the error is an object. JSON.stringify can parse and stringify strings, numbers, objects, and arrays.

alioguzhan avatar Jan 20 '24 13:01 alioguzhan

thanks. welcome for the contribution. let's see what's the error first. my thought was only to decorate the error. maybe we could do something like that:

      try {
        const client = await getDevToolsPluginClientAsync(pluginName);
        setClient(client);
      } catch (e) {
        e.message = 'Failed to setup client from useDevToolsPluginClient: ' + e.message;
        setError(e);
      }

Kudo avatar Jan 20 '24 16:01 Kudo

Will do it when I get home @Kudo,

In addition to that, Should we replace the e.toString() with JSON.stringify(e) ? I can create a PR for that. toString fails when the error is an object. JSON.stringify can parse and stringify strings, numbers, objects, and arrays.

My goto for errors is usually:

String(error)

as JSON.stringify can throw depending on the object it gets, calling String() has the same functionality as .toString() or Error.prototype.message but handles any value safely.

jthoward64 avatar Jan 20 '24 17:01 jthoward64

the downside of new Error(...) is that we will miss the original stack trace. since we will rethrow the exception later, it would be good if we can find a way to keep the original stack.

Kudo avatar Jan 22 '24 03:01 Kudo

Well, there is Error.prototype.cause but IDK how much support there is for that

jthoward64 avatar Jan 22 '24 04:01 jthoward64

that's why i'd tried for e.message = 'Failed to setup client from useDevToolsPluginClient: ' + e.message; and not to re-create a new Error instance.

Kudo avatar Jan 22 '24 12:01 Kudo

I am back.

But I couldn't get the error message content. Editing the file under node_modules is not working because both expo run and eas build and even eas build --local are not using my modified node_modules folder. They all run npm install internally.

And this error doesn't exist in the local development environment (npx expo start). So I think 2 options here:

1 - I will fork this repository, edit that file, and add my fork as a dependency instead of this one. 2 - We will replace that toString() part with String(e) and release a new version of devtools plugin (if possible)

What do you suggest ?

alioguzhan avatar Jan 22 '24 17:01 alioguzhan

Will do it when I get home @Kudo, In addition to that, Should we replace the e.toString() with JSON.stringify(e) ? I can create a PR for that. toString fails when the error is an object. JSON.stringify can parse and stringify strings, numbers, objects, and arrays.

My goto for errors is usually:

String(error)

as JSON.stringify can throw depending on the object it gets, calling String() has the same functionality as .toString() or Error.prototype.message but handles any value safely.

I didn't know that JSON.stringify could throw depending on the object. And looks like you are right. This is from MDN:

Thrown in one of the following cases:

  • value contains a circular reference.
  • A BigInt value is encountered.

But String() does not throw for any value. Thanks for the tip @jthoward64

alioguzhan avatar Jan 22 '24 17:01 alioguzhan

But I couldn't get the error message content. Editing the file under node_modules is not working because both expo run and eas build and even eas build --local are not using my modified node_modules folder. They all run npm install internally.

good to know it's using eas build. in this case you may need to modify and use patch-package to generate the patch and on postinstall to apply the patch.

Kudo avatar Jan 22 '24 17:01 Kudo

I think this is the error message:

{ isTrusted: false, message: [Getter/Setter] }

But I am not sure 100%. Does this make any sense in this context ? If not I can keep digging. @Kudo

alioguzhan avatar Jan 22 '24 18:01 alioguzhan

looks strange to me, having no idea how it comes from. could you try to dump to stack trace?

Kudo avatar Jan 22 '24 18:01 Kudo

Sorry for the limited feedback. It is hard to work with update -> patch -> build -> install to emulator -> adb logs flow :) I will update here If I find more.

alioguzhan avatar Jan 22 '24 18:01 alioguzhan

no worries! after you generate builds from eas build, you may try to modify node_modules/expo locally before running npx expo start, then you don't need to re-resubmit eas build again.

Kudo avatar Jan 22 '24 18:01 Kudo

OK. I was not able to reproduce this on compiled apps. Once a new version is released that fixes that error logging, I will try that again.

I will create a separate issue for that. (or maybe a PR ?)

Btw, if the error is something like { isTrusted: false, message: [Getter/Setter] }, then using String(e) also returns [object Object]. The only method that outputs a proper stringified version was JSON.stringify(e) for me. @Kudo @jthoward64

alioguzhan avatar Jan 26 '24 06:01 alioguzhan

The only method that outputs a proper stringified version was JSON.stringify(e) for me. @Kudo @jthoward64

You just have to be careful using JSON.stringify because if it throws you will mask the initial error completely. What I usually do (more complex) is use a try catch to prefer JSON.stringify and fallback to String

jthoward64 avatar Jan 26 '24 07:01 jthoward64

Yes, that's also what I thought. try/catch for JSON stringify and String makes sense. That's also what I used for encoding/decoding scalars for GraphQL.

alioguzhan avatar Jan 26 '24 09:01 alioguzhan

Im have the same error but only in my production build, when i build the same commit to development it runs ok

DarlonHenrique avatar Jun 21 '24 18:06 DarlonHenrique

I also don't get this in development, but release builds hang after the splash screen hides -- looks to be during the initial render. I was able to log the error with JSON.stringify(e), but the stack trace isn't super helpful.

Error: Failed to setup client from useDevToolsPluginClient: {"isTrusted":false,"message":"The operation couldn’t be completed. Connection refused"}

This error is located at:
    in AppNavigator
    in RCTView
    in Unknown
    in TouchListener
    in RNCSafeAreaProvider
    in SafeAreaProvider
    in App
    in ReactNativeProfiler
    in RCTView
    in Unknown
    in __Sentry.TouchEventBoundary
    in RootApp
    in RCTView
    in Unknown
    in RCTView
    in Unknown
    in AppContainer, js engine: hermes

bpeltonc avatar Jun 24 '24 12:06 bpeltonc

I'm using this patch as a workaround. I'm not sure that throwing from the hook is the best way to handle errors in this case. Obviously, we should understand what is the root cause of the error and fix that, but I'm thinking there also might be a better way to handle the errors, since this implementation breaks the app entirely.

diff --git a/node_modules/expo/build/devtools/index.js b/node_modules/expo/build/devtools/index.js
index 25c7e7c..560fdfd 100644
--- a/node_modules/expo/build/devtools/index.js
+++ b/node_modules/expo/build/devtools/index.js
@@ -33,7 +33,8 @@ export function useDevToolsPluginClient(pluginName) {
         };
     }, [pluginName]);
     if (error != null) {
-        throw error;
+        // throw error;
+        console.log(`An error was caught in useDevToolsPluginClient: ${JSON.stringify(error)}`);
     }
     return client;
 }

bpeltonc avatar Jun 24 '24 16:06 bpeltonc

Also seeing a similar issue using drizzle dev tools: https://github.com/drizzle-team/drizzle-studio-expo/issues/1

osamaqarem avatar Jun 25 '24 06:06 osamaqarem

@osamaqarem thanks for saving my day 👍

similar issue using drizzle dev tools

likaci avatar Jul 24 '24 14:07 likaci

@osamaqarem thanks a lot I had this issue for week now it gone after remove useDrizzleStudio()

abdibaker avatar Sep 09 '24 07:09 abdibaker

Also seeing a similar issue using drizzle dev tools: drizzle-team/drizzle-studio-expo#1

Thank you 😭

tasmto avatar Sep 22 '24 08:09 tasmto

I had similar issue and I solved using variable EXPO_PUBLIC_DISABLE_FEATURE=true to use drizzle studio only at development env.

 if (!process.env.EXPO_PUBLIC_DISABLE_FEATURE) {
        useDrizzleStudio(expoDb)
    }

kimuradev avatar Oct 10 '24 21:10 kimuradev

Using the __DEV__ flag to handle it is a nice way to circumvent this:

if (__DEV__) {
  useDrizzleStudio(expoDb);
}

victorlap avatar Dec 10 '24 08:12 victorlap

What's the solution for this? I can't access any dev tools plugin. It works for a brief second then everything in div#root Is removed from the DOM.

The console error logs this message: Screenshot 2025-01-02 at 12 00 23 AM

pfcodes avatar Jan 02 '25 05:01 pfcodes

I had the same problem with the production build and Apollo Client Dev Tools. I messed up the import (auto-import 🙈) so it missed the ENV check at the index.js.

- import { useApolloClientDevTools } from '@dev-plugins/apollo-client/build/useApolloClientDevTools';
+ import { useApolloClientDevTools } from '@dev-plugins/apollo-client';

pchalupa avatar Jan 16 '25 13:01 pchalupa