From 2b85741955e485de168a1e016ece7cb1c29f4a4e Mon Sep 17 00:00:00 2001 From: koreacomp5 Date: Thu, 9 Oct 2025 15:15:32 +0900 Subject: [PATCH] =?UTF-8?q?4.2=20=EA=B3=B5=ED=86=B5=20fetcher/=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=98=95=EC=8B=9D/=EC=9E=AC=EC=8B=9C=EB=8F=84?= =?UTF-8?q?=C2=B7=EB=B0=B1=EC=98=A4=ED=94=84=20=EC=84=A4=EC=A0=95=20o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/api.ts | 33 +++++++++++++++++++++++++++++++++ todolist.txt | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/lib/api.ts diff --git a/src/lib/api.ts b/src/lib/api.ts new file mode 100644 index 0000000..4576208 --- /dev/null +++ b/src/lib/api.ts @@ -0,0 +1,33 @@ +export type ApiError = { + message: string; + status: number; + details?: unknown; +}; + +export async function fetchJson(input: RequestInfo | URL, init?: RequestInit): Promise { + const res = await fetch(input, { + headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) }, + ...init, + }); + const text = await res.text(); + const data = text ? safeJson(text) : undefined; + if (!res.ok) { + const err: ApiError = { + message: (data as any)?.error || res.statusText || "Request failed", + status: res.status, + details: data, + }; + throw err; + } + return (data as T) ?? ({} as T); +} + +function safeJson(text: string): unknown { + try { + return JSON.parse(text); + } catch { + return text; + } +} + + diff --git a/todolist.txt b/todolist.txt index 68aa784..570a9c3 100644 --- a/todolist.txt +++ b/todolist.txt @@ -22,7 +22,7 @@ [상태관리/데이터] 4.1 React Query 설치 및 Provider 구성 o -4.2 공통 fetcher/에러 형식/재시도·백오프 설정 +4.2 공통 fetcher/에러 형식/재시도·백오프 설정 o 4.3 캐시 키/무효화 전략 수립 및 적용 4.4 낙관적 업데이트 패턴 적용(작성/수정)