{"record":{"id":"837a586d4e2baee5","repo":"mantinedev/mantine","slug":"request-failed-with-status-res-status","errorCode":null,"errorMessage":"Request failed with status ${res.status}","messagePattern":"Request failed with status (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@mantine/hooks/src/use-fetch/use-fetch.ts","lineNumber":36,"sourceCode":"): UseFetchReturnValue<T> {\n  const [data, setData] = useState<T | null>(null);\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState<Error | null>(null);\n  const controller = useRef<AbortController | null>(null);\n\n  const refetch = useCallback(() => {\n    if (controller.current) {\n      controller.current.abort();\n    }\n\n    controller.current = new AbortController();\n\n    setLoading(true);\n\n    return fetch(url, { ...options, signal: controller.current.signal })\n      .then((res) => {\n        if (!res.ok) {\n          throw new Error(`Request failed with status ${res.status}`);\n        }\n        return res.json();\n      })\n      .then((res) => {\n        setData(res);\n        setLoading(false);\n        return res as T;\n      })\n      .catch((err) => {\n        setLoading(false);\n\n        if (err.name !== 'AbortError') {\n          setError(err);\n        }\n\n        return err;\n      });\n  }, [url, JSON.stringify(options)]);","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/mantinedev/mantine/blob/8a284e2c2c53a9cb6f39f5dc389bf41b7a2073f8/packages/@mantine/hooks/src/use-fetch/use-fetch.ts#L18-L54","documentation":"useFetch from @mantine/hooks wraps fetch and throws an Error with the HTTP status code when the response is not ok (status outside 200-299). The thrown error is captured in the hook's error state, so it typically surfaces as error.message in your UI rather than an uncaught exception.","triggerScenarios":"GET request to an endpoint returning 404, 401, 500, etc.; wrong URL path; expired auth token; backend down while returning error statuses via a proxy.","commonSituations":"API base URL misconfigured between dev/prod; hitting a route that does not exist in the mock server; auth session expired making the endpoint return 401/403; rate limiting returning 429.","solutions":["Check error.message in the hook result and surface it in the UI instead of crashing","Fix the URL or request options causing the non-2xx response","Handle auth expiry: refresh the token and refetch() on 401","Use the returned refetch to retry after transient server errors"],"exampleFix":"// before\nconst { data, loading, error } = useFetch(url);\nif (loading) return <Loader />;\nreturn <div>{data.message}</div>;\n\n// after\nconst { data, loading, error } = useFetch(url);\nif (loading) return <Loader />;\nif (error) return <div>Request failed: {error.message}</div>;\nreturn <div>{data.message}</div>;","handlingStrategy":"fallback","validationCode":"const { data, error, loading, refetch } = useFetch(url);\n// no pre-call validation possible; guard the result\nif (error) {\n  // handle non-2xx gracefully\n}","typeGuard":null,"tryCatchPattern":"// useFetch already captures the error in state — render defensively:\nif (error) return <ErrorMessage onRetry={refetch}>{error.message}</ErrorMessage>;","preventionTips":["Always check error and loading before using data","Centralize API base URLs per environment","Refresh auth tokens on 401 and call refetch"],"tags":["http","fetch","use-fetch","status-code"],"backgroundTag":"http-request-failed","analyzedSha":"8a284e2c2c53a9cb6f39f5dc389bf41b7a2073f8","analyzedAt":"2026-08-28T10:25:51.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}