React Native app does not crash as expected - react-native

We have been investigating issues in our app where we just see a white screen and no crash is logged. Goes for both Android and iOS
The issue seem to be related to the use of async/await or promises.
We have found that we can reproduce the white screen issue locally when using async/await or promises.
The issue can be reproduced with the following code (tried to simplify it as much as possible). Replace App.js in a new project with the following:
import React, {Fragment} from 'react';
import {Text} from 'react-native';
class App extends React.Component {
state = {isMounted: false};
async componentDidMount() {
await Promise.resolve(1);
this.setState({isMounted: true});
}
render() {
if (this.state.isMounted) {
this.state.isMounted.test();
}
return (
<Fragment>
<Text>test</Text>
</Fragment>
);
}
}
export default App;
I also pushed a test project on github
I would expect the app to crash as isMounted does not contains a test method.
When running locally I get the red box stating that an error occurred as expected
TypeError: this.state.isMounted.test is not a function. (In 'this.state.isMounted.test()', 'this.state.isMounted.test' is undefined)
This error is located at:
in App (at renderApplication.js:40)
in RCTView (at View.js:35)
in View (at AppContainer.js:98)
in RCTView (at View.js:35)
in View (at AppContainer.js:115)
in AppContainer (at renderApplication.js:39)
...
but when running a release build the app does not crash and no error is reported. This makes it very hard for us to find and fix issues like this as we are totally blind.
If I comment out
await Promise.resolve(1);
It crash as expected in a release build
React Native version: 0.60.5
Are we wrong in assuming that the above code should result in an app crash?

Found that error-boundaries was the missing piece. Implementing an error boundary on the root level allows us to manually log these errors to our crash handling system.
As a side note I can also mention that if you use redux-saga and you throw an error, the error by default seem to be swallowed. So if you want to handle these uncaught errors you can implement the onError option in createSagaMiddleware

Related

How to fix the SSRProvider Warning in React Native

I am using NativeBase with my ReactNative App.
It is running ok.
However there is a warning that is bugging me a little bit.
How do I fix the warning below?
When server rendering, you must wrap your application in an
to ensure consistent ids are generated between the
client and server.
FormControl#http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.wenyang.DanceConnectyCube:162364:111
RCTView View
First install this package
npm i #react-aria/ssr or yarn add #react-aria/ssr
Then import it into your App.js
import {SSRProvider} from '#react-aria/ssr';
Then do this
const App = () => {
return (
<SSRProvider>
<NativeBaseProvider>
<App />
</NativeBaseProvider>
</SSRProvider>
);
};

ComponentDidCatch isn't catching SVG Render errors

My team uses a general RenderErrorWrapper component everywhere. Looks basically like this
export class RenderErrorWrapper extends React.PureComponent<RenderErrorWrapperProps, RenderErrorWrapperState> {
constructor(props: RenderErrorWrapperProps) {
super(props)
this.state = { renderComponentSuccessful: true }
}
componentDidCatch(error: Error) {
this.setState({ renderComponentSuccessful: false })
}
render() {
if (!this.state.renderComponentSuccessful) {
this.props.fallbackComponent
}
return this.props.children
}
}
Now the thing is, this thing works. We know it works, it's a standard pattern for us, we see the errors this is catching, see the fallback UIs it displays.
Except.
We're also using the SvgUri component from react-native-svg-uri. Specifically the call we're doing is like
<SvgUri width={width} height={height} svgXmlData={xmlString} />
Now, if that xmlString isn't invalid, crazy things happen. We get an exception that bubbles all the way up, straight through our RenderErrorWrapper. We literally see the RenderErrorWrapper in the stack trace, but its ComponentDidCatch never gets called!
Invariant Violation: Text strings must be rendered within a <Text> component.
This error is located at:
in RNSVGGroup (at G.js:23)
in G (at Svg.js:127)
in RNSVGSvgView (at Svg.js:116)
in Svg (at react-native-svg-uri/index.js:168)
in RCTView (at View.js:45)
in View (at react-native-svg-uri/index.js:288)
in SvgUri (created by MyComponent)
in RenderErrorWrapper (created by MyComponent)
in RCTView (at View.js:45)
<< etc >>
I know react-native-svg-uri is an abandoned library at this point, unfortunately we're basically stuck with it. What I'm more concerned about is how this exception manages to miss our error handling framework entirely, since that could happen with other issues as well.
What makes this error special that it can bypass our error handling?
Figured out what's going on here: The problem is that RNSVGGroup is a Native component called by the SVG renderer, and Native errors skip your React Native error catch layers.
You can still catch and log the error but you have to use a native error handler to catch the native error first, and it won't save you from the Red Screen of Death. Alternatively, newer versions of react-native-svg might not have this issue, ours is pretty old.

mainBundlePath is Null for node package

I am using the package react-native-coreml and running into this error at startup.
My intention is to use this package to use a CoreML package in my react native app. I am running this within EXPO if that makes any difference.
I can't even run the app. These two errors are together.
Unable to start your application. Please refer to https://expo.fyi/no-registered-application for more information.
and
TypeError: null is not an object (evaluating 'RNCoreML.mainBundlePath')
- node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
Obviously the first error isn't useful, just including for thoroughness.
My implementation is as follows:
import React, { useState } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import FaceScanner from './FaceScanner';
import { classifyImage } from "react-native-coreml";
const Onboarding = () => {
const [imageURL, setImageURL] = useState('');
const [tested, setTested] = useState(false);
console.log(imageURL)
if (imageURL !== '' && !tested) {
async () => {
// const { label, confidence } = await classifyImage(imageURL, './model.mlmodelc')
setTested(true);
console.log("The image is a " + label + ". I think. ")
}
}
...
edit I have ejected from expo as per a comment's suggestion. I am now encountering these errors.
BUNDLE ./index.js
ERROR TypeError: null is not an object (evaluating 'RNCoreML.mainBundlePath')
LOG Running "main" with {"rootTag":1,"initialProps":{}}
ERROR Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
react-native-coreml is a library with native extensions that do not work in the expo managed workflow currently. you can read about the managed workflow limitations in the expo docs.
if you'd like to use it, run expo eject and build the project in xcode

Invariant Violation: Calling synchronous methods on native modules is not supported in Chrome

I have forked this React library for use with React Native and have got it working by installing react-native-svg, use-elapsed-time and prop-types:
https://github.com/vydimitrov/react-countdown-circle-timer
However I now am not able to use the debugger:
Invariant Violation: Calling synchronous methods on native modules is
not supported in Chrome.
Consider providing alternative methods to expose this method in debug
mode, e.g. by exposing constants ahead-of-time.
This error is located at:
in CountdownCircleTimer (at AppRoot.js:118)
in AppRoot (at App.js:9)
in Provider (at App.js:8)
in App (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in RCTView (at AppContainer.js:119)
I have searched high and low for any clues as to which package could be causing the error and I can only see the issue reported relating to react-native-device-info but this is not causing the problem. What does the error mean an how can I begin to debug this if there is such little information around about it?
This is temporary fix. This is working perfectly on my side. you have to edit this file
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js
callNativeSyncHook(
moduleID: number,
methodID: number,
params: any[],
onFail: ?Function,
onSucc: ?Function,
): any {
const isDebuggingEnabled = (typeof atob !== 'undefined');
this.processCallbacks(moduleID, methodID, params, onFail, onSucc);
if(!isDebuggingEnabled)
{
return global.nativeCallSyncHook(moduleID, methodID, params);
}
}
you can also use patch-package to patch it permanently.
underlaying issue
For anyone else landing here from a Google search, things seem to have changed greatly since 2011 in regards to this issue (which isn't surprising).
If you try #MuhammadNuman's solution you will just get a different error about global.nativeCallSyncHook not being a function.
The workaround I'm using for this is to simply return anything else from callNativeSyncHook. E.g.:
callNativeSyncHook(
moduleID: number,
methodID: number,
params: any[],
onFail: ?Function,
onSucc: ?Function,
): any {
const isDebuggingEnabled = (typeof atob !== 'undefined');
this.processCallbacks(moduleID, methodID, params, onFail, onSucc);
if (!isDebuggingEnabled) {
return "Meh, I have no idea what's going on here, but at least this gets rid of the annoying error!";
}
}
I'd be very interested to know if there's a "proper" way to fix this post 2011, but for now this is good enough for me.
There is no need to modify or patch any npm package for this anymore.
The issue is fixed by react native 0.66.
Ref:
Stack Overflow Answer
Github Issue/Comment
I am using RN 0.67.3. This error was found in Galaxy S22 in debug mode.
I rerun yarn android and the error has gone.

I'm getting this error in my simulator when trying to render React Native app

This is my first time using react native. I am following a tutorial but my results are different than the tutorial. I've triple checked my code and its exactly as its shown but I'm getting this error. Any ideas?
// Import a library to help create a Component
import React from 'react';
import { Text, AppRegistry } from 'react-native';
// Create a Component
const App = () => (
<Text>Some Text</Text>
);
// Render it to the device
AppRegistry.registerComponent('albums', () => App);
The error is
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in.
Check the render method of `AwakeInDevApp`.
in AwakeInDevApp (at registerRootComponent.js:21)
in ExponentRootComponent (at renderApplication.js:35)
in RCTView (at View.js:128)
in View (at AppContainer.js:93)
in RCTView (at View.js:128)
in View (at AppContainer.js:92)
in AppContainer (at renderApplication.js:34)
Screenshot of Error in Simulator
Try to change 'albums' to 'AwakeInDevApp', it must be your project name when you run react-native init YourProjectName