Obsługa błędów z axiosa

0

Jak się obsługuje globalnie błędy z axiosa w Reakcie? Chciałbym, żeby po otrzymaniu np. 500 przekierować użytkownika automatycznie do jakiejś strony z błędem, podobnie w przypadku 401 i 404. Jak na razie napisałem jakieś bazowe fetch, w którym robię try/catch i przekierowuję korzystając z globalnego obiektu history. Tak się to obecnie robi czy może jakoś nowocześnie przy użyciu Context API i hooków? I czy może w ogóle lepiej wyświetlić jakieś powiadomienie w przypadku błędu zamiast przekierowywać do innej strony?

1

Może hook useEffect, a w nim w function(error) robisz switcha i w zależności od kodu błędu robisz przekierowanie? Przekierowanie w przypadku kodu błędu jest częstą praktyką i jest ok.

0

@Haskell Znalazłem taką bibliotekę: https://github.com/tannerlinsley/react-query. Tu oni sugerują, żeby robić if/else przy renderowaniu komponentu.

function Todos() {
  const { data, isLoading, error } = useQuery('todos', fetchTodoList)

  return (
    <div>
      {isLoading ? (
        <span>Loading...</span>
      ) : error ? (
        <span>Error: {error.message}</span>
      ) : data ? (
        <ul>
          {data.map(todo => (
            <li key={todo.id}>{todo.title}</li>
          ))}
        </ul>
      ) : null}
    </div>
  )
}

Myślałem też o napisaniu jakiegoś hooka useFetch, takiego jak tu: https://blog.blackbox-vision.tech/fetch-data-using-react-hooks

1

Zobacz sobie jak działają "Interceptors": https://www.npmjs.com/package/axios#interceptors

W callbacku odpalanym w przypadku błędu zrób sobie switcha na error.response.status (kody http odpowiedzi) i tam zrób sobie przekierowania gdzie chcesz. Pamiętaj tylko, że jeżeli nie wywołasz tam żadnego przekierowania i jednocześnie callback ten nie zwróci Promise.reject to kod wyżej nie wyłapie tego w catchu.

0

Na podstawie tego, co robi się na backendzie, napisałem sobie jakieś bazowe callAPI, w którym przechwytuję te wyjątki i zwracam jakiś Result.

const result = await fetchSomething(...)
if (result.success) setData(result.data)
else setError(result.error)
setIsLoading(false)

@alkyms Automatyczne przekierowywanie wydaje się być bardzo wygodne, tylko trochę dziwnie to wygląda, jak wywołanie funkcji odpytującej API przekierowuje na inną stronę. Sam już nie wiem.

1

Hmmm... jeśli masz taką potrzebę aby zrobić jakieś przekierowanie w momencie gdy API zwróci Ci np. 402 to nie widzę w tym nic dziwnego.

Zerknij może na ten filmik. Nie oglądałem go do końca ale gość tutaj chce chyba właśnie coś podobnego sklecić co może CI się przydać:

0

Fajne, tylko że on robi mniej więcej coś podobnego do tego, co napisałem w drugim poście. Tylko że używa do tego useReducer (myślałem, że useReducer używa się, jak się ma, nie wiem, 10 useState'ów, a nie 4 - jak to z tym jest?).

W sumie taka opcja z try/catch + interceptor wydaje się być chyba najlepsza. Te błędy, które wiemy jak obsłużyć niezależnie od komponentu, obsługujemy w interceptorze, a komponent obsługuje pozostałe.

1

useReducer jest alternatywą dla useState natomiast ja postrzegam to tak, że należy go używać nie jako zamiennika lecz w sytuacjach gdy nasz nowy stan ma być zależny od poprzedniego. try/catch + interceptor może się udać, jednak będzie miało jedną wadę. Za każdym razem w komponencie będziesz musiał jakoś definiować wychwytywanie i reagowanie na błędy niezdefiniowane wcześniej. W dużej aplikacji gdzie będzie sporo odwołań do API będziesz notorycznie łamał zasadę DRY bo przecież jeśli jakieś błędy będą występowały to będą powtarzalne i powinny być wykrywane przynajmniej poziom wyżej niż komponent z którego wychodzi request.

0

No właśnie. Jak żyć?

0

Ten problem zostanie rozwiązany, jak Suspense będzie gotowe. :) https://pl.reactjs.org/docs/concurrent-mode-suspense.html#handling-errors
With Suspense, handling fetching errors works the same way as handling rendering errors — you can render an error boundary anywhere to “catch” errors in components below.

React to jednak przyszłość.

1 użytkowników online, w tym zalogowanych: 0, gości: 1