DEV Community

Leonardo Muniz
Leonardo Muniz

Posted on

Arquitetura Resiliente no React: Usando Error Boundaries

Recentemente estava implementando numa página um leitor de pdf para uma revista, testei no browser desktop e tudo funcionava perfeitamente.

O problema nasceu no mobile, pois após avançar algumas páginas do pdf o site quebrava completamente: “Application error: a client-side exception has occurred (see the browser console for more information).”.

Console error img

Resumo do conteúdo

Não vou falar da solução, mas sim de como evitar que sua aplicação quebre completamente nesses casos, utilizando o conceito de Error Boundary para apresentar um UI alternativa em caso de erro.

Tela de erro nao tratada

Tela de erro nao tratada

UI com tratamento de error boundary

UI com tratamento de error boundary

Antes do React 16, um erro em qualquer componente poderia levar a falhas em toda a aplicação, pois o erro era propagado (intensionalmente, nao é um bug, é uma feature mesmo🫣), quebrando completamente o site e criando uma experiência ruim para o usuário. Com a chegada do React 16, os Error Boundaries foram introduzidos, permitindo que desenvolvedores capturassem e tratassem erros em componentes específicos, sem derrubar toda a aplicação.

O que são Error Boundaries? 🔗

Error Boundaries são componentes React que capturam erros JavaScript em seus componentes filhos, registram esses erros e exibem uma interface de fallback em vez do componente que falhou, funcionando como um catch{} para componentes.

Atualmente, é disponível somente como componente de classe e, até o momento, não há indícios da equipe do React querer mudar isso (ok, oficialmente nao tem, mas voce vai encontrar formas de fazer isso tanto manualmente quanto com libs externas e falarei disso mais pra frente.)

Exemplo de código:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logErrorToService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Algo deu errado.</h1>;
    }
    return this.props.children;
  }
}

Enter fullscreen mode Exit fullscreen mode

Vamos entender melhor o papel das funções:

  • getDerivedStateFromError: Esta função estática é usada para atualizar o estado local do componente e renderizar uma UI de fallback após um erro.
  • componentDidCatch: Este método é acionado após um erro ser capturado pelo Error Boundary. É útil para registro de erros ou efeitos colaterais.

Ao usar o Error Boundary em sua aplicação, envolva os componentes que você deseja proteger:

<ErrorBoundary>
 <SeuComponente />
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

Voce tambem pode envolver toda a aplicacao, tambem pode envolver o conteudo do site excluindo o layout ou ate mesmo somente rotas, tudo depende do design que voce escolher e que fizer mais sentido no seu contexto.

Quando usar e quando não usar 🔗

Quando usar:

  • Em componentes ou funcionalidades não críticas.
  • Quando incorporar widgets ou bibliotecas de terceiros.

Quando não usar:

  • Para erros esperados (como erros de API conhecidos).
  • Dentro de manipuladores de eventos.
  • Em erros que devem ser tratados de maneira específica e não genérica.
  • Código assíncrono: Error Boundaries não capturam erros em operações assíncronas fora de componentes React, como setTimeout ou requestAnimationFrame. Para tratar erros em operações assíncronas dentro de componentes, você deve usar blocos try/catch.
  • Renderização do lado do servidor
  • Erros lançados no próprio Error Boundary.

Opcionais: 🔗

  • Integre Error Boundaries a soluções de monitoramento de erros para rápida identificação e correção, voce pode integrar com Sentry ou Exceptionless por exemplo.
  • Teste seus Error Boundaries para garantir que eles funcionem como esperado em diferentes cenários.

Bibliotecas de Terceiros: react-error-boundary 🔗

Enquanto os Error Boundaries nativos do React são poderosos, algumas bibliotecas de terceiros foram desenvolvidas para simplificar e enriquecer essa funcionalidade. Uma das mais populares é a react-error-boundary.

Principais benefícios:

API Simplificada: Com react-error-boundary, você pode criar um boundary de erro com uma simples função de fallback, sem a necessidade de criar uma classe componente, alem de oferecer diversas outras possibilidades, que nao irei tratar hoje.

exemplo com react-error-boundary:


import { ErrorBoundary } from 'react-error-boundary'

function FallbackComponent({ error }) {
  return <div>Ocorreu um erro: {error.message}</div>
}

<ErrorBoundary FallbackComponent={FallbackComponent}>
  <SeuComponente />
</ErrorBoundary>

Enter fullscreen mode Exit fullscreen mode

Hooks e Utilitários Adicionais: A biblioteca oferece o hook useErrorHandler, que permite capturar e tratar erros dentro de componentes funcionais e funções personalizadas.

Reinicialização Automática: Com a propriedade onReset, você pode definir como o componente deve se reiniciar após um erro.

Top comments (0)