hono rpc, typesafe하게 사용하기-2
이전글에서 좀더 나은 방향을 찾아서 코드만 작성해둔다.
ky를 같이 쓰고, hono-rpc-query까지 사용하는 방안이다.
ky에서는 statusCode에 따라 에러도 throw 해준다.
import { hcQuery } from "hono-rpc-query";
import ky from "ky";
const baseUrl =
env.DEV && env.BASE_URL === "/" ? "http://localhost:3001" : env.BASE_URL;
const kyapi = ky.extend({
hooks: {
beforeRequest: [
(request) => {
const { jwt } = useAuthStore.getState();
if (jwt) {
request.headers.set("Authorization", `Bearer ${jwt}`);
}
},
],
},
});
const client = hcWithType(baseUrl, {
fetch: (input: RequestInfo | URL, requestInit?: RequestInit) => {
return kyapi(input, {
timeout: 8000,
method: requestInit?.method,
headers: {
"content-type": "application/json",
...requestInit?.headers,
},
body: requestInit?.body,
});
},
});
export const api = hcQuery(client);
- 에러 핸들링
export const mapError = async (error: Error) => {
if (error instanceof HTTPError) {
try {
const errJson: ServerErrorJson = await error.response.json();
return {
code: errJson.code,
message: errJson.message,
err: error,
} as const;
} catch (_err) {
const err = _err as Error;
return {
code: "UN_KNOWN",
message: err.message,
err: err,
} as const;
}
}
if (error instanceof TimeoutError) {
return {
code: "TIME_OUT",
message: error.message,
err: error,
} as const;
}
return {
code: "UN_KNOWN",
message: error.message,
err: error,
} as const;
};
export const handleApiError =
(
errHandler: (
err: Awaited<ReturnType<typeof mapError>>,
) => void | Promise<void>,
) =>
async (err: Error) =>
errHandler(await mapError(err));