{"record":{"id":"7d839efc84f9c61d","repo":"honojs/hono","slug":"fetchres-status-fetchres-statustext","errorCode":null,"errorMessage":"${_fetchRes.status} ${_fetchRes.statusText}","messagePattern":"\\$\\{_fetchRes\\.status\\} \\$\\{_fetchRes\\.statusText\\}","errorType":"exception","errorClass":"DetailedError","httpStatus":null,"severity":"error","filePath":"src/client/fetch-result-please.ts","lineNumber":34,"sourceCode":"    _data: any\n    /**\n     * @description BodyInit property from whatwg-fetch polyfill\n     *\n     * @link https://github.com/JakeChampion/fetch/blob/main/fetch.js#L238\n     */\n    _bodyInit?: any\n  }\n\n  const hasBody =\n    (_fetchRes.body || _fetchRes._bodyInit) && !nullBodyResponses.has(_fetchRes.status)\n\n  if (hasBody) {\n    const responseType = detectResponseType(_fetchRes)\n    _fetchRes._data = await _fetchRes[responseType]()\n  }\n\n  if (!_fetchRes.ok) {\n    throw new DetailedError(`${_fetchRes.status} ${_fetchRes.statusText}`, {\n      statusCode: _fetchRes?.status,\n      detail: {\n        data: _fetchRes?._data,\n        statusText: _fetchRes?.statusText,\n      },\n    })\n  }\n\n  return _fetchRes._data\n}\n\nexport class DetailedError extends Error {\n  /**\n   * Additional `message` that will be logged AND returned to client\n   */\n  public detail?: any\n  /**\n   * Additional `code` that will be logged AND returned to client","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/client/fetch-result-please.ts#L16-L52","documentation":"fetchRP is Hono's tiny RPC/fetch client. After optionally consuming the response body, it checks `response.ok` and throws a DetailedError whose message is the HTTP status line (e.g. \"404 Not Found\"), attaching statusCode, parsed body data, and statusText. This is how non-2xx responses surface to the caller.","triggerScenarios":"Any request where the server responds with a 4xx/5xx status: hitting a wrong RPC route/path, missing route method, auth failure (401/403), validation failure (400/422), server error (500), or a proxy returning an error page.","commonSituations":"RPC client/server route mismatch after refactoring; forgetting to await an error-handling middleware; gateway timeouts behind reverse proxies; calling endpoints requiring auth without credentials; the HTML error pages of dev proxies being returned instead of JSON.","solutions":["Inspect the caught DetailedError: `err.statusCode` and `err.detail.data` usually contain the server's error body — log them to find the real cause","Fix the route/method/URL to match the server-side definition (verify with the typed client or a manual curl)","Add auth headers or middleware that was omitted","Add error-handling middleware (app.onError) on the server so 500s return meaningful JSON","If a proxy is involved, check its logs/config for the failing upstream"],"exampleFix":"// before\nconst res = await client.hello.$get()\nconst data = await res.json() // throws '404 Not Found' via fetchRP\n\n// after\ntry {\n  const res = await client.hello.$get()\n} catch (e) {\n  if (e instanceof DetailedError) console.error(e.statusCode, e.detail.data)\n  throw e\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { DetailedError } from 'hono/client/fetch-result-please'\n// (or duck-type)\nconst isDetailedHttpError = (e: unknown): e is { statusCode?: number; detail?: unknown } =>\n  typeof (e as any)?.statusCode === 'number'","tryCatchPattern":"try {\n  const res = await client.posts.$get()\n} catch (e) {\n  if (typeof (e as any)?.statusCode === 'number') {\n    const { statusCode, detail } = e as any\n    if (statusCode === 404) /* missing route */\n    else if (statusCode >= 500) /* server-side, maybe retry */\n    else /* 4xx: inspect detail.data for validation info */\n  }\n  throw e\n}","preventionTips":["Always await RPC calls inside try/catch; non-2xx throws rather than returning res.ok=false","Log e.detail.data — it carries the server's error body","Keep client and server route definitions in sync via the shared AppType type"],"tags":["client","rpc","http-status","fetch","detailed-error"],"backgroundTag":"http-request-failed","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}