Error Handling w React
Error Boundary (react-error-boundary), typed errors, Result pattern, TanStack Query, Sentry i Next.js error.tsx.
6 wzorców error handling w React
Error Boundary, react-error-boundary, try/catch, Result pattern, TanStack Query i Sentry — typ, zastosowanie i kiedy używać.
| Wzorzec | Typ | Zastosowanie |
|---|---|---|
| Error Boundary | Renderowanie | Izoluj sekcje — brak crash całej strony |
| react-error-boundary | Biblioteka | Async errors, resetKeys, FallbackComponent |
| try/catch + typed errors | Async | Fetch, API — ApiError, NetworkError instanceof |
| Result pattern | Functional | Brak throw — {ok: true, value} | {ok: false, error} |
| TanStack Query throwOnError | Data fetching | Propaguj błąd do Error Boundary |
| Sentry + global handler | Monitoring | Capture wszystkich błędów — unhandledrejection |
Często zadawane pytania
Error Boundaries w React — jak chronić komponenty przed crashem?
Error Boundary: komponent łapiący błędy w drzewie potomnym. Klasa komponenty (hooks brak!). componentDidCatch — obsługa błędu. getDerivedStateFromError — aktualizuj state. Podstawowy Error Boundary: class ErrorBoundary extends React.Component { state = {hasError: false, error: null}. static getDerivedStateFromError(error) { return {hasError: true, error} }. componentDidCatch(error, errorInfo) { logToSentry(error, errorInfo.componentStack) }. render() { if (this.state.hasError) return this.props.fallback || div Something went wrong /div. return this.props.children } }. Użycie: ErrorBoundary fallback={ErrorFallback}. Dashboard /. /ErrorBoundary. Kiedy NIE łapie: Async errors (fetch, setTimeout) — użyj try/catch. Event handlers — użyj try/catch. SSR errors — Next.js error.tsx. Granularne Error Boundaries: Wrap tylko krytyczne sekcje. Nie cała aplikacja w jednym EB. Fallback per sekcja. react-error-boundary (zalecana biblioteka): npm install react-error-boundary. import {ErrorBoundary, useErrorBoundary} from 'react-error-boundary'. Hooki: useErrorBoundary(). const {showBoundary} = useErrorBoundary(). showBoundary(error) — rzuć błąd z async. Obsługa async! FallbackComponent: const ErrorFallback = ({error, resetErrorBoundary}) => div. Przycisk reset. error.message. Retry logic. onReset prop. Reset na navigation z resetKeys prop. React 19 — use() + Suspense + Error boundary: Pełny pattern async.
Obsługa błędów asynchronicznych — fetch, API i TanStack Query?
try/catch w async: try { const data = await fetchUsers() } catch (error) { if (error instanceof TypeError) { setError('Network error') } else if (error instanceof ApiError) { setError(error.message) } }. Typed errors: class ApiError extends Error { constructor(public status: number, message: string) { super(message). this.name = 'ApiError' } }. async function fetchUser(id: string): Promise(User) { const res = await fetch('/api/users/' + id). if (!res.ok) { throw new ApiError(res.status, await res.text()) } return res.json() }. Result pattern (bez throw): type Result(T, E = Error) = {ok: true, value: T} | {ok: false, error: E}. async function safeRequest(url: string): Promise(Result(Response)) { try { const res = await fetch(url). return {ok: true, value: res} } catch (e) { return {ok: false, error: e as Error} } }. TanStack Query error handling: const {data, error, isError} = useQuery({queryKey: ['user', id], queryFn: () => fetchUser(id)}). if (isError) return ErrorComponent error={error}. error typed jako Error. onError callback (deprecated v5). TanStack Query v5 error: throwOnError: true — rzuć do Error Boundary. meta.errorHandler. Global error handling: queryClient.setDefaultOptions({queries: {retry: 1, onError: (error) => logError(error)}}). useMutation error: mutation.error. onError callback. isError state. Axios interceptors: axios.interceptors.response.use(null, error => { if (error.response?.status === 401) redirectToLogin(). return Promise.reject(error) }).
Sentry — integracja error tracking z React?
Sentry: error monitoring SaaS. npm install @sentry/react. Inicjalizacja (main.tsx/index.tsx): import * as Sentry from '@sentry/react'. Sentry.init({dsn: process.env.REACT_APP_SENTRY_DSN, environment: process.env.NODE_ENV, integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()], tracesSampleRate: 0.1, replaysSessionSampleRate: 0.1}). Sentry Error Boundary: import {withSentryReactRouterV6Routing} from '@sentry/react'. Sentry.ErrorBoundary: fallback={({error, resetError}) => div. Automatycznie raportuje błąd. Context: Sentry.setUser({id: userId, email}). Sentry.setTag('feature', 'checkout'). Sentry.setContext('order', {id: orderId, total}). Manualne raportowanie: try {...} catch (error) { Sentry.captureException(error). setError(error) }. Sentry.captureMessage('Warn: slow request'). Performance: Sentry.startTransaction({name: 'checkout', op: 'navigation'}). Source maps: sentry-cli upload-source-maps. Lub @sentry/webpack-plugin. Fingerprinting: grouping podobnych błędów. Alerts: Slack, email, PagerDuty. Threshold-based (np. 10 errors/min). Sentry Session Replay: Record user interactions. Reprodukcja błędu step-by-step. Maskowanie PII automatyczne. Next.js Sentry: @sentry/nextjs. npx @sentry/wizard@latest -i nextjs. Automatyczna konfiguracja. Error pages owinięte. Ignorowanie błędów: ignoreErrors: [/ResizeObserver loop/]. Zbyt wiele false positives. Filtering.
Global error handling i React error patterns?
Global window.onerror: window.addEventListener('unhandledrejection', (event) => { logError(event.reason). event.preventDefault() }). Łapie Promise rejections. Uzupełnienie Error Boundary. window.onerror — synchroniczne błędy. Toasty dla błędów: sonner lub react-hot-toast. toast.error(error.message). Nie przerywaj UX — tylko informuj. Sentry + toast: Sentry.captureException(error). toast.error('Coś poszło nie tak'). User feedback: Sentry User Feedback. dialog po błędzie. Komentarz od użytkownika. Retry mechanisms: exponential backoff. const retry = async (fn, retries = 3, delay = 1000) => { for (let i = 0; i... await new Promise(r => setTimeout(r, delay * 2 ** i)). try { return await fn() } catch(e) { if (i === retries-1) throw e } }. TanStack Query retry: retry: 3. retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000). Error hierarchy: BaseError extends Error. NetworkError extends BaseError. AuthError extends BaseError. ValidationError extends BaseError. Structured catch: instanceof check. Różne handling per type. TypeScript narrowing. Error boundaries + fallback UI: SkeletonFallback dla loading. ErrorFallback z retry button. ResetBoundary — klucz zmienia się przy nawigacji. Stale state problem. Accessibility dla błędów: role='alert' na error messages. aria-live='polite' dla async errors. focus management po błędzie. Formularze: error per field. aria-describedby dla error message. pattern — client validation. Nie tylko serwer-side.
Error handling w Next.js — error.tsx, not-found.tsx i middleware?
App Router error files: error.tsx — per route segment error boundary. global-error.tsx — root level fallback. not-found.tsx — 404 strona. loading.tsx — Suspense fallback. error.tsx: 'use client'. export default function Error({error, reset}: {error: Error & {digest?: string}, reset: () => void}) { return div h2 Coś poszło nie tak /h2. button onClick={reset} Spróbuj ponownie /button /div }. error.digest — ID błędu (server-side). reset() — retry render. global-error.tsx: Łapie błędy root layout. Zawiera html i body! Ostatni fallback. not-found.tsx: notFound() — throw z Server Component. 404 status automatycznie. Custom 404 per segment. Server Component errors: Rzucone w Server Component -> error.tsx. try/catch w Server Action: return {error: message}. Nie throw — klient musi obsłużyć. Pages Router: _error.tsx — custom error page. _app.tsx z ErrorBoundary dla client errors. getServerSideProps — throw przekieruje do _error. API Routes error: return res.status(400).json({error: message}). HTTP status codes semantyczne. Middleware error handling: next.config.ts — error redirects. Custom 404/500 pages. Redirect przy błędzie auth. Structured API errors: { code: 'VALIDATION_ERROR', message: 'Invalid email', details: {field: 'email', value: 'invalid'} }. Konsystentny format. Łatwy frontend handling. zod.safeParse().error.flatten() dla walidacji. Monitoring: Sentry + Next.js — auto integration. Server Components errors — server-side capture. Client errors — client-side capture.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz