dev-plugins
dev-plugins copied to clipboard
App crashes on splash screen
Thanks for the great work for Expo 50.
I enabled the DevTools plugin for react-navigation in my index.tsx file:
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.
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)
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.
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);
}
Will do it when I get home @Kudo,
In addition to that, Should we replace the
e.toString()withJSON.stringify(e)? I can create a PR for that.toStringfails 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.
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.
Well, there is Error.prototype.cause but IDK how much support there is for that
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.
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 ?
Will do it when I get home @Kudo, In addition to that, Should we replace the
e.toString()withJSON.stringify(e)? I can create a PR for that.toStringfails 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()orError.prototype.messagebut 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
But I couldn't get the error message content. Editing the file under
node_modulesis not working because bothexpo runandeas buildand eveneas build --localare not using my modifiednode_modulesfolder. They all runnpm installinternally.
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.
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
looks strange to me, having no idea how it comes from. could you try to dump to stack trace?
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.
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.
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
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
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.
Im have the same error but only in my production build, when i build the same commit to development it runs ok
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
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;
}
Also seeing a similar issue using drizzle dev tools: https://github.com/drizzle-team/drizzle-studio-expo/issues/1
@osamaqarem thanks for saving my day 👍
similar issue using drizzle dev tools
@osamaqarem thanks a lot I had this issue for week now it gone after remove useDrizzleStudio()
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)
}
Using the __DEV__ flag to handle it is a nice way to circumvent this:
if (__DEV__) {
useDrizzleStudio(expoDb);
}
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:
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';