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?
Obsługa błędów z axiosa
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Gdańsk
- Postów: 647
- Rejestracja: dni
- Ostatnio: dni
- Postów: 4700
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.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Gdańsk
- Postów: 647
@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
- Rejestracja: dni
- Ostatnio: dni
- Postów: 15
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.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Gdańsk
- Postów: 647
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 15
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ć:
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Gdańsk
- Postów: 647
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 15
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.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Gdańsk
- Postów: 647
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ść.