Skip to content

Commit

Permalink
refactor: 공통 api 함수 에러 처리 리팩터링 (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
saseungmin authored Sep 8, 2024
1 parent 24826ec commit 2399d56
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 52 deletions.
13 changes: 9 additions & 4 deletions src/app/api/auth/callback/kakao/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,17 @@ export async function POST(request: NextRequest) {
});

return response;
} catch (error: any) {
const errorResponse = error as FetchError;
} catch (error) {
if (error instanceof FetchError) {
return NextResponse.json(null, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json(null, {
status: errorResponse.response?.status,
statusText: errorResponse.message,
status: 500,
statusText: 'Internal Server Error',
});
}
}
12 changes: 8 additions & 4 deletions src/app/api/my/favorite-places/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ export async function GET(request: NextRequest) {
items: favoritePlaces,
});
} catch (error) {
const fetchError = error as FetchError;
if (error instanceof FetchError) {
return NextResponse.json(null, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json(null, {
status: fetchError.response?.status || 500,
statusText: fetchError.response?.statusText || fetchError.message,
headers: fetchError.response?.headers,
status: 500,
statusText: 'Internal Server Error',
});
}
}
12 changes: 8 additions & 4 deletions src/app/api/search/nearby/places/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ export async function GET(request: NextRequest) {
status: 200,
});
} catch (error) {
const fetchError = error as FetchError;
if (error instanceof FetchError) {
return NextResponse.json(null, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json(null, {
status: fetchError.response?.status,
statusText: fetchError.response?.statusText,
headers: fetchError.response?.headers,
status: 500,
statusText: 'internal server error',
});
}
}
12 changes: 8 additions & 4 deletions src/app/api/search/places/[placeId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ export async function GET(request: NextRequest) {
},
});
} catch (error) {
const fetchError = error as FetchError;
if (error instanceof FetchError) {
return NextResponse.json(null, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json(null, {
status: fetchError.response?.status || 500,
statusText: fetchError.response?.statusText || fetchError.message,
headers: fetchError.response?.headers,
status: 500,
statusText: 'internal server error',
});
}
}
12 changes: 8 additions & 4 deletions src/app/api/search/places/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@ export async function GET(request: NextRequest) {
status: 200,
});
} catch (error) {
const fetchError = error as FetchError;
if (error instanceof FetchError) {
return NextResponse.json(null, {
status: error.status,
statusText: error.message,
});
}

return NextResponse.json(null, {
status: fetchError.response?.status,
statusText: fetchError.response?.statusText,
headers: fetchError.response?.headers,
status: 500,
statusText: 'internal server error',
});
}
}
73 changes: 42 additions & 31 deletions src/lib/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,10 @@ import qs from 'qs';
import { FetchRequest, UrlPrefixType } from '../types/api';

export class FetchError extends Error {
constructor(
response: Response,
errorMessage = '',
) {
super();
this.response = response;
this.message = errorMessage;
constructor(public status: number, message: string) {
super(message);
this.name = 'FetchError';
}

response?: Response;
}

export const paramsSerializer = <T>(params: T): string => qs.stringify(params, {
Expand All @@ -32,39 +26,56 @@ export const getUrl = (url: string, type: UrlPrefixType) => {
return `${process.env.NEXT_PUBLIC_API_HOST}${url}`;
};

async function api<T, K = any>({
async function api<T, K = unknown>({
url, params, config = {}, headers, type = 'public', method = 'GET',
}: FetchRequest<K>): Promise<T> {
const defaultHeader = type === 'public' ? { 'nfteam-api-token': process.env.API_HEADER_TOKEN } : undefined;
const defaultHeader = new Headers(headers);

if (type === 'public') {
defaultHeader.set('nfteam-api-token', process.env.API_HEADER_TOKEN);
}

const googleKey = type === 'google' ? { key: process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY } : undefined;

const response = await fetch(`${getUrl(url, type)}?${paramsSerializer({
const defaultParams = paramsSerializer({
...params,
...googleKey,
})}`, {
...config,
headers: {
...defaultHeader,
...headers,
...(config?.body ? {
Accept: 'application/json',
'Content-Type': 'application/json',
} : {}),
},
method,
});

if (!response.ok) {
throw new FetchError(response, response.statusText);
}
try {
const response = await fetch(`${getUrl(url, type)}${defaultParams ? `?${defaultParams}` : ''}`, {
headers: {
...defaultHeader,
...headers,
...(config?.body ? {
Accept: 'application/json',
'Content-Type': 'application/json',
} : {}),
},
method,
...config,
});

if (response.status === 204) {
return null as T;
}
if (!response.ok) {
const errorBody = await response.json().catch(() => ({}));

throw new FetchError(response.status, errorBody?.message || response.statusText);
}

if (response.status === 204) {
return null as T;
}

const data = await response.json() as Promise<T>;
const data = await response.json() as T;

return data;
return data;
} catch (error) {
if (error instanceof FetchError) {
throw error;
}

throw new FetchError(500, 'An unexpected error occurred');
}
}

export default api;
2 changes: 1 addition & 1 deletion src/lib/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Method =

export type UrlPrefixType = 'public' | 'google' | 'bff';

export interface FetchRequest<T = any> {
export interface FetchRequest<T = unknown> {
url: string;
params?: T;
method?: Method;
Expand Down

0 comments on commit 2399d56

Please sign in to comment.