Граница ошибки не перехватывает ошибку от клиента Apollo - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь поймать некоторые ошибки на верхнем уровне, чтобы показать самую красивую страницу ошибок в мире.

По какой-то причине я вижу, что мои узлы отключены, но Error Boundary никогда не срабатывает.

import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import ApolloClient, { gql } from 'apollo-boost';

const client = new ApolloClient({ uri: "/graphql" });
const query = gql`{ items { id }}`;

class ErrorBoundary extends React.Component {
  state = { hasError: false };

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

  render() {
    if (this.state.hasError) {
      return Had error
    } else {
      return this.props.children;
    }
  }
}

function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    client.query({ query })
      .then(res => setData(res))
      .catch(err => { console.warn("Error:", err); throw err; });
  }, []);

  return Data: {data}
; } ReactDOM.render ( , document.getElementById ('root'));

Я запускаю это в пустом проекте создания-реакции-приложения.

Я ожидаю увидеть <h1>Had error</h1>; Я получаю CRA необработанный экран ошибки.

1 Ответ

0 голосов
/ 19 февраля 2020

Из документов

Границы ошибок делают не ловить ошибки для:

  • Обработчики событий (узнать больше)
  • Асинхронный код (например, обратные вызовы setTimeout или requestAnimationFrame)
  • Рендеринг на стороне сервера
  • Ошибки, возникающие на самой границе ошибки (а не ее дочерних элементах)

Обещания асинхронны, поэтому отклоненные Обещания не будут обнаружены границами ошибок. На данный момент рекомендуемый, но несколько хакерский sh подход состоит в том, чтобы выбросить ошибку в setState. В функциональных компонентах вы можете использовать функцию set, возвращаемую хуком useState вместо setState:

const [, setState] = useState()
useEffect(() => {
  client.query({ query })
    .then(res => setData(res))
    .catch(err => {
      console.warn("Error:", err);
      setState(() => {
        throw err;
      });
    });
}, []);

Бросок внутрь useEffect также будет работать, но не внутри then или catch обратный вызов обещания. Вы также не можете сделать обратный вызов useEffect функцией async, потому что он не может вернуть Обещание. Таким образом, мы застряли с использованием setState.

Также обратите внимание, что на самом деле нет никаких оснований для непосредственного вызова client.query, особенно потому, что этот код не восстановит ваш пользовательский интерфейс, если изменения кеша. Вы должны использовать useQuery и состояние data, уже открытое для вас.

...