How to let react electron ignore undefined error? - javascript

React electron on windows, if A is null, call A.test will make the application stop working, then the user has to close the application and restart it.
How to let react ignore the error, and continue work. The code has many A.test, I can't write everywhere if(A) A.test.
If this can't be resolved, can I print the error on the web view? So I don't have to remote visit the user's computer to see the console error.

NOTE
I think the solution is to use react error boundaries, as suggested in the console.
You already pointed out that you're using error boundaries, so after testing your scenarios in this fiddle I believe your implementation might be incorrect.
Given a similar implementation for ErrorBoundary in the docs:
class ErrorBoundary extends React.Component {
state = { hasError: '' };
render() {
return this.state.hasError ? (
<span>Oops! Something went wrong:<br />{this.state.hasError}</span>
) : this.props.children;
}
}
ErrorBoundary.getDerivedStateFromError = (error) => ({ hasError: error.toString() });
This component will render the fallback when any of its children breaks.
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI
It will look similar to:
<MyReactApp>
<ErrorBoundary>
<ChatContent />
</ErrorBoundary>
</MyReactApp>
Now any error in ChatContent will be catch by ErrorBoundary giving you the opportunity to render the fallback like:
Oops! Something went wrong:
ReferenceError: test is not defined

The code has many A.test, I can't write every where if(A) A.test
But why? You can use some editor for multi file editing.
So you can replace A.test() to safeTest(A) function.
export const safeTest = (Obj) => {
if (Obj) {
Obj.test();
} else {
// Any action you want
}
}

It is hard to offer an answer to your question because I don't see your project codes, but if your react version is 16 you can use a special component lifecycle method that name is componentDidCatch.
Inside this method you will have these values:
componentDidCatch(error, info) {
// Do something with error and info
}
Even you can use setState inside this method and show you want. I think this method can help you for your second desire, the printing error in web view.

I tend to favor using default props. You can set a value for the component to assign to a prop if the prop is passed in undefined. For example, if your component depends on an array nested within an object, you could set that value as an empty array by default. This is especially handy when your component depends on an array of results from an API call, but the component renders before the request finishes.

If you want to make the minimal effort to catch all the unhandled errors from both main and renderer processes within Electron as well as showing them to the user via a dialog, the easy way is to use electron-unhandled which does exactly that:
After having installed it (npm i electron-unhandled), in both your main and renderer entry files (likely their root index.js), you just have to add, at the beginning:
const unhandled = require('electron-unhandled');
unhandled({ showDialog: true });
Now, that being said, it's a good practice to use a global error catcher but it's a really bad one if you use only that. You should try covering your error handling more accurately, at least method by method:
.then() { ... }.catch(err => ...) for your promises,
(..., (err, res) => { if (err !== null) { ... } ... ) for your callbacks,
try { ... } catch(err) { ... } for non-async or await-based code code parts.
And, as a side-note, I myself created a dependenciless library to make it safe and easy to create a global errors dictionary in order to well-organize your errors but there are other alternatives if this one doesn't fit your needs.

I guess the best possible solution to this would be surrounding your A.test in try and catch. In this case what you can do is catch the error is A is null and perform some error page from your side incase you want it or just keep the error silent incase you dont want to perform any operation and suppress the error and continue execution.
You can also wrap A.test in a function with try-catch and use that function instead of A.test. In this way you can avoid multiple try-catch block and you can handle the error as per your requirement here.

Related

How do you store state.Data and state.isValid in ADYEN Card Component?

So I've read the documentation and have followed everything so far. However, in the handleOnChange function, I cannot post the data because it gives the error:
ERROR
Here's how I'm currently trying to post the data, I'm open for any suggestions.
function handleOnChange(state, component) {
state.isValid
state.data
component
if (state.isValid === true) {
this.http.post(environment.paymentFunctionurl + '/', { amount: this.amount, content: state.data}).subscribe((res) => {
console.log(res);
})
}
}
I've tried storing them as variables but it results as undefined. What am I missing here?
Your error is with accessing http, it isn't part of this. You need to make sure http is added to this or likely put http on window so you can access it regardless of your scope.
Side note: your example is passing amount from the client.Do not do this in production!!!!
You might be just doing this while testing, but it's even bad practice in testing. A client may be malicious and change the amount and instead you should use your own backend/database to dictate how much to charge.

RxJs operators are not recognized while running angular tests

So, I have a component where I subscribe to change in value in one of the form control on ngOnInit life cycle. But while writing tests the tests for it, I get an error relating to skip not being a function.
My Component file looks like this
ngOnInit() {
this.buildForm();
this.cronTextSubscription = this.cronForm.get('emailCron').valueChanges
.skip(3)
.debounceTime(3000)
.distinctUntilChanged()
.subscribe(cronPattern => {
this.updateEmailCronPattern(cronPattern);
});
this.fetchCronExpression();
}
While running the test, I get the following error.
TypeError: this.cronForm.get(...).valueChanges.skip is not a function
I am new to testing in angular, so any help would be highly appreciated.
If this code works in the project but has issues in tests then you need to verify that in the test this.cronForm.get('emailCron') returns correct data.
Also you use here quite old rxjs syntax, please check your rxjs version. perhaps it's 6 (but in this case the project should fail too).
Then your code should look like:
ngOnInit() {
this.buildForm();
this.cronTextSubscription = this.cronForm.get('emailCron').valueChanges.pipe(
skip(3),
debounceTime(3000),
distinctUntilChanged(),
).subscribe(cronPattern => {
this.updateEmailCronPattern(cronPattern);
});
this.fetchCronExpression();
}

Why ErrorBoundary needed in React.js?

What kind of errors does it handle, and is there any real-world scenario?
I read the docs but it doesn't give a good example.
And docs also mention it handles UI errors, but UI errors can be solved at development time, so exactly why do we need "Error Boundaries".
Error Boundaries are like try-catch blocks for react components . They allow you to catch and handle unexpected errors in react components gracefully, for example, display a message to the user that something went wrong.
These errors, if not handled will crash your app. Error boundaries allow you to catch those errors and handle them in a way that prevents your app from crashing and instead provide a user friendly message to the user indicating that something went wrong.
Keep in mind that Error Boundaries do not handle errors for:
Event handlers
Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
Server side rendering
Errors thrown in the error boundary itself (rather than its children)
Here's a nice article that explains error boundaries
but UI errors can be solved at development time
UI errors can't be solved at development time, although typing like Flow & Typescript indeed help a lot, still, there may be run-time errors that usually come for the data server.
Error Boundaries used for catching run time errors and displaying a friendly UI.
See Compile time vs Run time errors.
ErrorBoundary is a class components that implements getDerivedStateFromError and componentDidCatch in order to add additional render on fall back UI.
Currently, it can only be implemented with a class component, typically its the only class component in your application, the rest is function components with hooks.
In real-life use cases, you wrap your application with some <ErrorBoundary/> component and render the desired UI.
class ErrorBoundary extends React.Component {
state = {
hasError: false,
error: { message: '', stack: '' },
info: { componentStack: '' }
};
static getDerivedStateFromError = error => {
return { hasError: true };
};
componentDidCatch = (error, info) => {
this.setState({ error, info });
};
render() {
const { hasError, error, info } = this.state;
const { children } = this.props;
return hasError ? <ErrorComponent/> : children;
}
}
<ErrorBoundary>
<App/>
</ErrorBoundary>

How to check if a JSON object is present in a file in JavaScript

I am building an app in react-native and have been trouble getting some trouble doing error checking. I am using redux and thunk to store a JSON file from the API that I am searching from. Sometimes, the search will lead back with a JSON file that contains an error message(most likely due to spelling error or unsure about what I am exactly searching for). I am trying to build a function in my app that will run in an componentWillMount function that first checks if the file has an error meassage and if so will send it back to the home screen to redo the search. The problem that am encountering is that I do not know what to code inorder to see what the error is or even if there is an error to begin with.
this is what the error object will look like in the JSON file and this
"error": {
"type": "NameResolutionException",
"message": "Name resolution error: Taxon 'Mallard' or 'Bat' resolve to multiple nodes"
},
This is the function that I built
componentDidMount = () => {
console.log("STATE", this.state);
if(this.props.response.articles.error == undefined){
if(this.props.response.articles.error.type === "NameResolutionException"){
Alert.alert("Please Refine Search or Specify Taxon.")
.then(()=>this.props.navigation.navigate("Home"));
}
}
};
The if statements will never hit despite the fact that the json file will the error object in it.
The expected output is that the error will be caught and then the app will go back to its the home screen but instead the app will fail because certain components will be missing.
Your code seems not correct, you are saying if error is undefined then comparing for a string value. This is contradictory.
It should be something like this, considering error is an object not an array
componentDidMount = () => {
console.log("STATE", this.state);
if(this.props.response.articles.error && this.props.response.articles.error.type){ // considering error object may or may not be present
if(this.props.response.articles.error.type === "NameResolutionException"){
Alert.alert("Please Refine Search or Specify Taxon.")
.then(()=>this.props.navigation.navigate("Home"));
}
else if (this.props.response.articles.error.type === "OtherPossibleStringException"){
}
else {
//Any unhandled error case
}
}
};

using a destroyed view for changeDetection in ngAfterViewInit

A private (but open source) Angular package in the organisation I work for has some code that looks like this:
ngAfterViewInit(): void {
setTimeout(() => {
this.changeDetector.detectChanges();
// do more things
});
}
We implement this package in our application (the package is to introduce common components so that front-end devs across the org don't implement things multiple times, and to enforce a common design language for consistency). However, when using the component this is called in, and showing and then destroying the component repeatedly, eventually it will stop working, with this error in the console:
Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
I'm trying to find a way of making sure the code above is not being run if the component has already been destroyed. I have considered using the ngOnDestroy lifecycle method:
ngOnDestroy(): void {
this.changeDetector.detach();
}
but I'm not sure what else I would put in there to check the view is ok. I also thought about something like:
if (!this.changeDetector.destroyed) {
this.changeDetector.detectChanges();
}
but nothing like destroyed exists on ChangeDetectorRef.
What is the correct way of ensuring this error does not show and the component works, even when repeatedly showing and destroying it?
I think the best solution I have found is to use !ViewRef.destroyed and if that returns truthy then proceed, otherwise don't.
if (!(this.changeDetector as ViewRef).destroyed) {
this.changeDetector.detectChanges()
// do other tasks
}
I think destroyed does work but the syntax is like this:
if (!this.changeDetector['destroyed']) {
this.changeDetector.detectChanges();
}
Then obviously, just keep the code you have on your ngOnDestroy hook.

Categories

Resources