David Omar Flores
David Omar Flores

Reputation: 93

ErrorBoundary not catching error thrown by imported function

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

Answers (1)

Daniel Tehrani
Daniel Tehrani

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

Related Questions