diff --git a/src/app/api/qna/detail/route.ts b/src/app/api/qna/detail/route.ts index 5490fb3..77a5ec0 100644 --- a/src/app/api/qna/detail/route.ts +++ b/src/app/api/qna/detail/route.ts @@ -1,8 +1,13 @@ -import { ERROR_MESSAGES, queryStringFormatter } from '@/utils/common-utils' +import { queryStringFormatter } from '@/utils/common-utils' import axios from 'axios' import { NextResponse } from 'next/server' import { loggerWrapper } from '@/libs/api-wrapper' -import { HttpStatusCode } from 'axios' +import { QnaService } from '../service' +import { ApiError } from 'next/dist/server/api-utils' +import { getIronSession } from 'iron-session' +import { SessionData } from '@/types/Auth' +import { sessionOptions } from '@/libs/session' +import { cookies } from 'next/headers' /** * @api {GET} /api/qna/detail 문의 상세 조회 API @@ -21,60 +26,52 @@ import { HttpStatusCode } from 'axios' * @apiSuccessExample {json} Success-Response: * { * "data": { - "compCd": "5200", - "qnaNo": 51, - "qstTitle": "Q.CAST TEST", - "qstContents": "Q.CAST TEST CONTENTS", - "regDt": "2025.04.29 16:16:51", - "regId": "X112", - "regNm": "株式会社アイ工務店", - "regEmail": "x112@interplug.co.kr", - "answerYn": "N", - "ansContents": null, - "ansRegDt": null, - "ansRegNm": null, - "ansListFile": null, - "storeId": "X112", - "storeNm": "株式会社アイ工務店", - "regUserNm": "TEST", - "regUserTelNo": "010-1111-1111", - "qnaClsLrgCd": "A01", - "qnaClsMidCd": "B02", - "qnaClsSmlCd": "C05", - "listFile": [ - { - "fileNo": 853 - "encodeFileNo": 853, - "srcFileNm": "Quotation_4500380_20240808145129.pdf", - "fileCours": "/temp/20250428/" - "fileSize":160982, - "regDt":"2024.08.13" - } - ... - ], - ... - }, + * "compCd": "5200", + * "qnaNo": 51, + * "qstTitle": "Q.CAST TEST", + * "qstContents": "Q.CAST TEST CONTENTS", + * "regDt": "2025.04.29 16:16:51", + * "regId": "X112", + * "regNm": "株式会社アイ工務店", + * "regEmail": "x112@interplug.co.kr", + * "answerYn": "N", + * "ansContents": null, + * ... + * "listFile": [ + * { + * "fileNo": 853 + * "encodeFileNo": 853, + * "srcFileNm": "Quotation_4500380_20240808145129.pdf", + * "fileCours": "/temp/20250428/" + * "fileSize":160982, + * "regDt":"2024.08.13" + * } + * ... + * ], + * }, + * }, * @apiError {Number} 401 세션 정보 없음 (로그인 필요) * @apiError {Number} 500 서버 오류 */ async function getQnaDetail(request: Request): Promise { + const cookieStore = await cookies() + const session = await getIronSession(cookieStore, sessionOptions) + + const service = new QnaService(session) const { searchParams } = new URL(request.url) const params = { compCd: searchParams.get('compCd'), qnaNo: searchParams.get('qnoNo'), langCd: searchParams.get('langCd'), - loginId: searchParams.get('loginId'), } - try { - const response = await axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/detail?${queryStringFormatter(params)}`) - if (response.status === 200) { - return NextResponse.json(response.data) - } - return NextResponse.json({ error: response.data.result }, { status: response.status }) - } catch (error: any) { - return NextResponse.json({ error: error.response.data.result ?? ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError }) + const result = await service.tryFunction(() => + axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/detail?loginId=${session.userId}&${queryStringFormatter(params)}`), + ) + if (result instanceof ApiError) { + return NextResponse.json({ error: result.message }, { status: result.statusCode }) } + return NextResponse.json(result.data) } export const GET = loggerWrapper(getQnaDetail) diff --git a/src/app/api/qna/file/route.ts b/src/app/api/qna/file/route.ts index 8d6ea8a..2b9fd7a 100644 --- a/src/app/api/qna/file/route.ts +++ b/src/app/api/qna/file/route.ts @@ -2,6 +2,8 @@ import { HttpStatusCode } from 'axios' import { NextResponse } from 'next/server' import { loggerWrapper } from '@/libs/api-wrapper' import { ERROR_MESSAGES } from '@/utils/common-utils' +import { QnaService } from '../service' +import { ApiError } from 'next/dist/server/api-utils' /** * @api {GET} /api/qna/file 문의 첨부 파일 다운로드 API @@ -22,6 +24,7 @@ import { ERROR_MESSAGES } from '@/utils/common-utils' * @apiError {Number} 400 잘못된 요청 */ async function downloadFile(request: Request): Promise { + const service = new QnaService() const { searchParams } = new URL(request.url) const encodeFileNo = searchParams.get('encodeFileNo') const srcFileNm = searchParams.get('srcFileNm') || 'downloaded-file' @@ -32,26 +35,21 @@ async function downloadFile(request: Request): Promise { const url = `${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/file/downloadFile2?encodeFileNo=${encodeFileNo}` - try { - const resp = await fetch(url) - - if (!resp.ok) { - return NextResponse.json({ error: ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError }) - } - - const contentType = resp.headers.get('content-type') || 'application/octet-stream' - const contentDisposition = resp.headers.get('content-disposition') || `attachment; filename="${srcFileNm}"` - - return new NextResponse(resp.body, { - status: 200, - headers: { - 'Content-Type': contentType, - 'Content-Disposition': contentDisposition, - }, - }) - } catch (error: any) { - return NextResponse.json({ error: error.response?.data ?? ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError }) + const resp = await service.tryFunction(() => fetch(url), true) + if (resp instanceof ApiError) { + return NextResponse.json({ error: resp.message }, { status: resp.statusCode }) } + + const contentType = resp.headers.get('content-type') || 'application/octet-stream' + const contentDisposition = resp.headers.get('content-disposition') || `attachment; filename="${srcFileNm}"` + + return new NextResponse(resp.body, { + status: 200, + headers: { + 'Content-Type': contentType, + 'Content-Disposition': contentDisposition, + }, + }) } export const GET = loggerWrapper(downloadFile) diff --git a/src/app/api/qna/list/route.ts b/src/app/api/qna/list/route.ts index 7d1d714..243c9e6 100644 --- a/src/app/api/qna/list/route.ts +++ b/src/app/api/qna/list/route.ts @@ -1,11 +1,13 @@ -import axios, { HttpStatusCode } from 'axios' +import axios from 'axios' import { NextResponse } from 'next/server' -import { ERROR_MESSAGES, queryStringFormatter } from '@/utils/common-utils' +import { queryStringFormatter } from '@/utils/common-utils' import { getIronSession } from 'iron-session' import { cookies } from 'next/headers' import { loggerWrapper } from '@/libs/api-wrapper' import { sessionOptions } from '@/libs/session' import { SessionData } from '@/types/Auth' +import { QnaService } from '../service' +import { ApiError } from 'next/dist/server/api-utils' /** * @api {GET} /api/qna/list 문의 목록 조회 API @@ -56,31 +58,16 @@ async function getQnaList(request: Request): Promise { const cookieStore = await cookies() const session = await getIronSession(cookieStore, sessionOptions) - if (!session.isLoggedIn) { - return NextResponse.json({ error: ERROR_MESSAGES.UNAUTHORIZED }, { status: HttpStatusCode.Unauthorized }) - } + const service = new QnaService(session) const { searchParams } = new URL(request.url) + const params = service.getSearchParams(searchParams) - const params: Record = {} - searchParams.forEach((value, key) => { - const match = key.match(/inquiryListRequest\[(.*)\]/) - if (match) { - params[match[1]] = value - } else { - params[key] = value - } - }) - - try { - const response = await axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/list?${queryStringFormatter(params)}`) - if (response.status === 200) { - return NextResponse.json(response.data) - } - return NextResponse.json({ error: response.data.result }, { status: response.status }) - } catch (error: any) { - return NextResponse.json({ error: error.response.data.result ?? ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError }) + const result = await service.tryFunction(() => axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/list?${queryStringFormatter(params)}`), true) + if (result instanceof ApiError) { + return NextResponse.json({ error: result.message }, { status: result.statusCode }) } + return NextResponse.json(result.data.data) } export const GET = loggerWrapper(getQnaList) diff --git a/src/app/api/qna/route.ts b/src/app/api/qna/route.ts index b9c0d64..767f9ca 100644 --- a/src/app/api/qna/route.ts +++ b/src/app/api/qna/route.ts @@ -1,7 +1,8 @@ import { NextResponse } from 'next/server' import axios from 'axios' -import { CommonCode } from '@/types/Inquiry' import { loggerWrapper } from '@/libs/api-wrapper' +import { QnaService } from './service' +import { ApiError } from 'next/dist/server/api-utils' /** * @api {GET} /api/qna 문의 유형 목록 조회 API @@ -31,20 +32,14 @@ import { loggerWrapper } from '@/libs/api-wrapper' * ... * } */ -async function getCommonCodeListData(request: Request): Promise { - const response = await axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/system/commonCodeListData`) - const codeList: CommonCode[] = [] - response.data.data.apiCommCdList.forEach((item: any) => { - if (item.headCd === '204200' || item.headCd === '204300' || item.headCd === '204400') { - codeList.push({ - headCd: item.headCd, - code: item.code, - name: item.codeJp, - refChar1: item.refChr1, - }) - } - }) - return NextResponse.json({ data: codeList }) +async function getCommonCodeListData(): Promise { + const service = new QnaService() + const response = await service.tryFunction(() => axios.get(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/system/commonCodeListData`)) + if (response instanceof ApiError) { + return NextResponse.json({ error: response.message }, { status: response.statusCode }) + } + const result = service.getInquiryTypeList(response.data.apiCommCdList) + return NextResponse.json({ data: result }) } export const GET = loggerWrapper(getCommonCodeListData) diff --git a/src/app/api/qna/save/route.ts b/src/app/api/qna/save/route.ts index 8e9af99..d042658 100644 --- a/src/app/api/qna/save/route.ts +++ b/src/app/api/qna/save/route.ts @@ -1,7 +1,12 @@ -import axios, { HttpStatusCode } from 'axios' +import axios from 'axios' import { NextResponse } from 'next/server' import { loggerWrapper } from '@/libs/api-wrapper' -import { ERROR_MESSAGES } from '@/utils/common-utils' +import { QnaService } from '../service' +import { ApiError } from 'next/dist/server/api-utils' +import { getIronSession } from 'iron-session' +import { SessionData } from '@/types/Auth' +import { sessionOptions } from '@/libs/session' +import { cookies } from 'next/headers' /** * @api {POST} /api/qna/save 문의 저장 API @@ -25,20 +30,22 @@ import { ERROR_MESSAGES } from '@/utils/common-utils' * @apiError {Number} 500 서버 오류 */ async function setQna(request: Request): Promise { + const cookieStore = await cookies() + const session = await getIronSession(cookieStore, sessionOptions) + + const service = new QnaService(session) const formData = await request.formData() - try { - const response = await axios.post(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/save`, formData, { + const result = await service.tryFunction(() => + axios.post(`${process.env.NEXT_PUBLIC_INQUIRY_API_URL}/api/qna/save`, formData, { headers: { 'Content-Type': 'multipart/form-data', }, - }) - if (response.status === 200) { - return NextResponse.json(response.data) - } - return NextResponse.json({ error: response.data.result }, { status: response.status }) - } catch (error: any) { - return NextResponse.json({ error: error.response.data.result ?? ERROR_MESSAGES.FETCH_ERROR }, { status: HttpStatusCode.InternalServerError }) + }), + ) + if (result instanceof ApiError) { + return NextResponse.json({ error: result.message }, { status: result.statusCode }) } + return NextResponse.json(result.data) } export const POST = loggerWrapper(setQna) diff --git a/src/app/api/qna/service.ts b/src/app/api/qna/service.ts new file mode 100644 index 0000000..b1ffc6b --- /dev/null +++ b/src/app/api/qna/service.ts @@ -0,0 +1,89 @@ +import { SessionData } from '@/types/Auth' +import { CommonCode } from '@/types/Inquiry' +import { ERROR_MESSAGES } from '@/utils/common-utils' +import { HttpStatusCode } from 'axios' +import { ApiError } from 'next/dist/server/api-utils' + +export class QnaService { + private session?: SessionData + constructor(session?: SessionData) { + this.session = session + } + /** + * @description API ROUTE 에러 처리 + * @param {any} error 에러 객체 + * @returns {ApiError} 에러 객체 + */ + private handleRouteError(error: any): ApiError { + console.error('❌ API ROUTE ERROR : ', error) + return new ApiError(error.response.status, error.response.data.result.message ?? ERROR_MESSAGES.FETCH_ERROR) + } + /** + * @description 비동기 함수 try-catch 처리 함수 + * @param {() => Promise} func 비동기 함수 + * @returns {Promise} 에러 객체 또는 함수 결과 + */ + async tryFunction(func: () => Promise, isFile?: boolean): Promise { + if (this.session !== undefined && !this.session?.isLoggedIn) { + return new ApiError(HttpStatusCode.Unauthorized, ERROR_MESSAGES.UNAUTHORIZED) + } + try { + const response = await func() + if (isFile) return response + return this.handleResult(response) + } catch (error) { + return this.handleRouteError(error) + } + } + + /** + * @description 함수 결과 처리 함수 + * @param {any} result 함수 결과 + * @returns {ApiError | any} 에러 객체 또는 함수 결과 + */ + private handleResult(response: any): ApiError | any { + if (response.status === HttpStatusCode.Ok) { + if (response.data.data !== null) return response.data + return new ApiError(HttpStatusCode.NotFound, ERROR_MESSAGES.NOT_FOUND) + } + return new ApiError(response.result.code, response.result.message) + } + + /** + * @description 문의 유형 타입 목록 조회 + * @param {string[]} responseList 문의 유형 타입 목록 + * @returns {CommonCode[]} 문의 유형 타입 목록 + */ + getInquiryTypeList(responseList: string[]): CommonCode[] { + const codeList: CommonCode[] = [] + responseList.forEach((item: any) => { + if (item.headCd === '204200' || item.headCd === '204300' || item.headCd === '204400') { + codeList.push({ + headCd: item.headCd, + code: item.code, + name: item.codeJp, + refChar1: item.refChr1, + }) + } + }) + return codeList + } + + /** + * @description 문의 목록 조회 파라미터 처리 + * @param {URLSearchParams} searchParams URLSearchParams 객체 + * @returns {Record} 문의 목록 조회 파라미터 + */ + getSearchParams(searchParams: URLSearchParams): Record { + const params: Record = {} + searchParams.forEach((value, key) => { + const match = key.match(/inquiryListRequest\[(.*)\]/) + if (match) { + params[match[1]] = value + } else { + params[key] = value + } + }) + return params + } +} diff --git a/src/app/api/submission/service.ts b/src/app/api/submission/service.ts index 431436c..f5f9a01 100644 --- a/src/app/api/submission/service.ts +++ b/src/app/api/submission/service.ts @@ -99,7 +99,7 @@ export class SubmissionService { error instanceof Prisma.PrismaClientUnknownRequestError || error instanceof Prisma.PrismaClientRustPanicError || error instanceof Prisma.PrismaClientValidationError || - error instanceof Prisma.PrismaClientUnknownRequestError + error instanceof Prisma.PrismaClientKnownRequestError ) { return new ApiError(HttpStatusCode.InternalServerError, ERROR_MESSAGES.PRISMA_ERROR) } diff --git a/src/app/api/survey-sales/service.ts b/src/app/api/survey-sales/service.ts index 8b75fb0..b2fb2b5 100644 --- a/src/app/api/survey-sales/service.ts +++ b/src/app/api/survey-sales/service.ts @@ -433,7 +433,7 @@ export class SurveySalesService { error instanceof Prisma.PrismaClientUnknownRequestError || error instanceof Prisma.PrismaClientRustPanicError || error instanceof Prisma.PrismaClientValidationError || - error instanceof Prisma.PrismaClientUnknownRequestError + error instanceof Prisma.PrismaClientKnownRequestError ) { return new ApiError(HttpStatusCode.InternalServerError, ERROR_MESSAGES.PRISMA_ERROR) } diff --git a/src/components/inquiry/Detail.tsx b/src/components/inquiry/Detail.tsx index f0ea5c0..3470c10 100644 --- a/src/components/inquiry/Detail.tsx +++ b/src/components/inquiry/Detail.tsx @@ -9,8 +9,7 @@ export default function Detail() { const params = useParams() const id = params.id - const { inquiryDetail, downloadFile } = useInquiry(Number(id), '5200') - const { commonCodeList } = useInquiry() + const { inquiryDetail, downloadFile, commonCodeList } = useInquiry(Number(id), false) const router = useRouter() const { session } = useSessionStore() diff --git a/src/components/inquiry/RegistForm.tsx b/src/components/inquiry/RegistForm.tsx index 7ad869e..3465063 100644 --- a/src/components/inquiry/RegistForm.tsx +++ b/src/components/inquiry/RegistForm.tsx @@ -7,7 +7,7 @@ import { InquiryRequest } from '@/types/Inquiry' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' export default function RegistForm() { - const { saveInquiry, isSavingInquiry } = useInquiry() + const { saveInquiry, isSavingInquiry, commonCodeList } = useInquiry(undefined, false) const { session } = useSessionStore() const router = useRouter() diff --git a/src/components/inquiry/list/ListTable.tsx b/src/components/inquiry/list/ListTable.tsx index b1359f7..ca7264a 100644 --- a/src/components/inquiry/list/ListTable.tsx +++ b/src/components/inquiry/list/ListTable.tsx @@ -25,7 +25,7 @@ export default function ListTable() { const router = useRouter() const pathname = usePathname() - const { inquiryList, isLoadingInquiryList } = useInquiry() + const { inquiryList, isLoadingInquiryList } = useInquiry(undefined, true) const { inquiryListRequest, setInquiryListRequest, reset, offset, setOffset } = useInquiryFilterStore() const [hasMore, setHasMore] = useState(false) diff --git a/src/hooks/useInquiry.ts b/src/hooks/useInquiry.ts index 707b0e0..5d0eff8 100644 --- a/src/hooks/useInquiry.ts +++ b/src/hooks/useInquiry.ts @@ -1,9 +1,8 @@ -import { InquiryList, Inquiry, InquirySaveResponse, CommonCode } from '@/types/Inquiry' +import { InquiryList, Inquiry, InquirySaveResponse, CommonCode, INQUIRY_ALERT_MSG } from '@/types/Inquiry' import { useAxios } from '@/hooks/useAxios' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useInquiryFilterStore } from '@/store/inquiryFilterStore' import { useMemo } from 'react' -import { useSessionStore } from '@/store/session' import { useRouter } from 'next/navigation' /** @@ -23,7 +22,7 @@ import { useRouter } from 'next/navigation' */ export function useInquiry( qnoNo?: number, - compCd?: string, + isList?: boolean, ): { inquiryList: InquiryList[] isLoadingInquiryList: boolean @@ -33,23 +32,27 @@ export function useInquiry( saveInquiry: (formData: FormData) => Promise downloadFile: (encodeFileNo: number, srcFileNm: string) => Promise commonCodeList: CommonCode[] + } { const queryClient = useQueryClient() const { inquiryListRequest, offset } = useInquiryFilterStore() - const { session } = useSessionStore() const { axiosInstance } = useAxios() const router = useRouter() - /** * @description API 에러 처리 및 라우팅 * * @param {any} error 에러 객체 * @returns {void} 라우팅 처리 */ - const errorRouter = (error: any) => { + const handleError = (error: any, isThrow?: boolean) => { const status = error.response?.status - if (error.response?.data.error) { - alert(error.response?.data.error) + const errorMsg = error.response?.data.error + console.error('❌ AXIOS INSTANCE ERROR : ', error) + if (errorMsg) { + showInquiryAlert(errorMsg) + } + if (isThrow) { + throw new Error(error) } switch (status) { // session 없는 경우 @@ -73,6 +76,25 @@ export function useInquiry( } } + /** + * @description 비동기 함수 try-catch 처리 함수 + * @param {() => Promise} func 비동기 함수 + * @param {boolean} isList 목록 조회 여부 + * @param {boolean} isThrow 에러 던지기 여부 + * @returns {Promise} 함수 결과 또는 빈 데이터 + */ + const tryFunction = async (func: () => Promise, isList?: boolean, isThrow?: boolean): Promise => { + try { + return await func() + } catch (error) { + handleError(error, isThrow) + if (isList) { + return { data: [], count: 0 } + } + return null + } + } + /** * @description 문의사항 목록 조회 * @@ -83,17 +105,20 @@ export function useInquiry( const { data: inquiryList, isLoading: isLoadingInquiryList } = useQuery({ queryKey: ['inquiryList', inquiryListRequest, offset], queryFn: async () => { - try { - const resp = await axiosInstance(null).get<{ data: InquiryList[] }>(`/api/qna/list`, { - params: { inquiryListRequest, startRow: offset, endRow: offset + 9 }, - }) - return resp.data.data - } catch (error: any) { - errorRouter(error) - return [] - } + const isListQuery = true + const shouldThrowError = false + + const resp = await tryFunction( + () => + axiosInstance(null).get<{ data: InquiryList[] }>(`/api/qna/list`, { + params: { inquiryListRequest, startRow: offset, endRow: offset + 9 }, + }), + isListQuery, + shouldThrowError, + ) + return resp.data }, - enabled: !!inquiryListRequest, + enabled: isList, }) /** @@ -119,19 +144,22 @@ export function useInquiry( * @returns {boolean} isLoading - 문의사항 상세 정보 로딩 상태 */ const { data: inquiryDetail, isLoading: isLoadingInquiryDetail } = useQuery({ - queryKey: ['inquiryDetail', qnoNo, compCd, session?.userId], + queryKey: ['inquiryDetail', qnoNo], queryFn: async () => { - try { - const resp = await axiosInstance(null).get<{ data: Inquiry }>(`/api/qna/detail`, { - params: { qnoNo, compCd, langCd: 'JA', loginId: session?.userId ?? '' }, - }) - return resp.data.data - } catch (error: any) { - errorRouter(error) - return null - } + const isListQuery = false + const shouldThrowError = false + + const resp = await tryFunction( + () => + axiosInstance(null).get<{ data: Inquiry }>(`/api/qna/detail`, { + params: { qnoNo, compCd: '5200', langCd: 'JA' }, + }), + isListQuery, + shouldThrowError, + ) + return resp?.data ?? null }, - enabled: qnoNo !== undefined && compCd !== undefined, + enabled: qnoNo !== undefined, }) /** @@ -142,14 +170,21 @@ export function useInquiry( */ const { mutateAsync: saveInquiry, isPending: isSavingInquiry } = useMutation({ mutationFn: async (formData: FormData) => { - const resp = await axiosInstance(null).post<{ data: InquirySaveResponse }>('/api/qna/save', formData) - return resp.data.data + const isListQuery = false + const shouldThrowError = true + + const resp = await tryFunction( + () => axiosInstance(null).post<{ data: InquirySaveResponse }>('/api/qna/save', formData), + isListQuery, + shouldThrowError, + ) + return resp?.data ?? null }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['inquiryList'] }) }, onError: (error: any) => { - errorRouter(error) + handleError(error, true) }, }) @@ -161,24 +196,21 @@ export function useInquiry( * @returns {Promise} 다운로드된 파일 데이터 또는 null */ const downloadFile = async (encodeFileNo: number, srcFileNm: string) => { - try { - const resp = await fetch(`/api/qna/file?encodeFileNo=${encodeFileNo}&srcFileNm=${srcFileNm}`) + const isListQuery = false + const shouldThrowError = true - const blob = await resp.blob() - const url = URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = srcFileNm - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - URL.revokeObjectURL(url) + const resp = await tryFunction(() => fetch(`/api/qna/file?encodeFileNo=${encodeFileNo}&srcFileNm=${srcFileNm}`), isListQuery, shouldThrowError) + const blob = await resp.blob() + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = srcFileNm + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) - return blob - } catch (error) { - alert('ファイルのダウンロードに失敗しました') - return null - } + return blob } /** @@ -191,7 +223,10 @@ export function useInquiry( const { data: commonCodeList, isLoading: isLoadingCommonCodeList } = useQuery({ queryKey: ['commonCodeList'], queryFn: async () => { - const resp = await axiosInstance(null).get<{ data: CommonCode[] }>(`/api/qna`) + const isListQuery = false + const shouldThrowError = false + + const resp = await tryFunction(() => axiosInstance(null).get<{ data: CommonCode[] }>(`/api/qna`), isListQuery, shouldThrowError) return resp.data }, staleTime: Infinity, diff --git a/src/hooks/useSurvey.ts b/src/hooks/useSurvey.ts index 98821a1..3e28744 100644 --- a/src/hooks/useSurvey.ts +++ b/src/hooks/useSurvey.ts @@ -114,7 +114,7 @@ export function useSurvey( const handleError = (error: any, isThrow?: boolean) => { const status = error.response?.status const errorMsg = error.response?.data.error - console.error('❌ API ERROR : ', error) + console.error('❌ AXIOS INSTANCE ERROR : ', error) if (errorMsg) { showSurveyAlert(errorMsg) }