Reputation: 93
I have a component wrapped in an Error Boundary, when a button is clicked a validate()
function is called, this function throws an error if there is not information provided however the ErrorBoundary
is not catching this error.
Render function on Component
return (
<ErrorBoundary>
...
<Playlist
...
onClick={this.addPlaylistToSpotify} // this function can throw an error
...
/>
</ErrorBoundary>
);
Function with error
addPlaylistToSpotify = () => {
try {
addPlaylist(this.state.newPlaylist); // this function throws an error on validate()
} catch (error) {
throw new Error(error);
}
...
};
ErrorBoundary Component
import React, { Component } from "react";
import { ErrorOverlay } from "../../components/index";
import styles from "./ErrorBoundary.css";
export class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: ""
};
}
componentDidCatch(error, errorInfo) {
this.setState({
hasError: true,
error: error,
errorInfo: errorInfo
});
// TODO: log the error somewhere in the db
}
dismiss() {
this.setState({
hasError: false,
error: null,
errorInfo: ""
});
}
render() {
if (this.state.hasError) {
return (
<ErrorOverlay message={this.state.errorInfo} dismiss={this.dismiss} />
);
} else {
return this.props.children;
}
}
}
Any help would be hugely appreciated, thanks! Any help would be hugely appreciated. Thanks!
Upvotes: 7
Views: 4580
Reputation: 136
From React docs
https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers
Note
Error boundaries do not catch 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)
In your code, the error is thrown from an event handler (addPlaylistToSpotify) so componentDidCatch can't catch the error. Therefore you need to do something like this:
import React from 'react';
export class Playlist extends React.Component {
constructor (props) {
super(props);
this.state = {
error: false
// ...
}
}
addPlaylistToSpotify = () => {
try {
// Something throws an error here.
} catch (error) {
this.setState({ error: true });
}
}
render() {
if (this.state.error) {
throw new Error('I crashed!');
}
return (
<div>
...
<button onClick={this.addPlaylistToSpotify}>Add song</button>
...
</div>
)
}
}
I hope this helps.
Upvotes: 9