fix: 메뉴 저장 실패 사유를 화면에 그대로 보여준다
백엔드가 success:false 봉투로 사유를 주는데("최상위 메뉴가 없습니다" 등) 액션이
전부 "저장하지 못했습니다"로 뭉개고 있었다. 통신 오류만 일반 문구로 남긴다.
menuIdPath는 조상 경로가 되도록 부모 경로 + 부모 id로 만든다. 백엔드가 값을 만들어
주지 않고 저장만 한다.
Co-Authored-By: Claude Opus 5
@3057371babec6b5560b85727495474fbf512516e
--- app/(protected)/(basic)/system/banned-words/_actions.ts
+++ app/(protected)/(basic)/system/banned-words/_actions.ts
... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 |
import { revalidatePath } from 'next/cache';
|
| 4 | 4 |
import { redirect } from 'next/navigation';
|
| 5 | 5 |
import { verifySession } from '@/lib/auth/dal';
|
| 6 |
+import { BackendRequestError } from '@/lib/http/backend-fetch';
|
|
| 6 | 7 |
import {
|
| 7 | 8 |
createBannedWord, |
| 8 | 9 |
deleteBannedWord, |
... | ... | @@ -20,6 +21,10 @@ |
| 20 | 21 |
const DELETE_FAILED_MESSAGE = '삭제하지 못했습니다. 잠시 후 다시 시도해 주세요.'; |
| 21 | 22 |
const UPLOAD_FAILED_MESSAGE = |
| 22 | 23 |
'엑셀 파일을 등록하지 못했습니다. 잠시 후 다시 시도해 주세요.'; |
| 24 |
+ |
|
| 25 |
+function failureMessage(error: unknown, fallback: string): string {
|
|
| 26 |
+ return error instanceof BackendRequestError ? error.message : fallback; |
|
| 27 |
+} |
|
| 23 | 28 |
|
| 24 | 29 |
function readString(formData: FormData, key: string): string {
|
| 25 | 30 |
const value = formData.get(key); |
... | ... | @@ -41,8 +46,8 @@ |
| 41 | 46 |
let result; |
| 42 | 47 |
try {
|
| 43 | 48 |
result = await createBannedWord(validation.value); |
| 44 |
- } catch {
|
|
| 45 |
- return { status: 'error', message: SAVE_FAILED_MESSAGE };
|
|
| 49 |
+ } catch (error) {
|
|
| 50 |
+ return { status: 'error', message: failureMessage(error, SAVE_FAILED_MESSAGE) };
|
|
| 46 | 51 |
} |
| 47 | 52 |
|
| 48 | 53 |
if (result.status === 'duplicate') {
|
... | ... | @@ -60,8 +65,8 @@ |
| 60 | 65 |
|
| 61 | 66 |
try {
|
| 62 | 67 |
await deleteBannedWord(id); |
| 63 |
- } catch {
|
|
| 64 |
- return { status: 'error', message: DELETE_FAILED_MESSAGE };
|
|
| 68 |
+ } catch (error) {
|
|
| 69 |
+ return { status: 'error', message: failureMessage(error, DELETE_FAILED_MESSAGE) };
|
|
| 65 | 70 |
} |
| 66 | 71 |
|
| 67 | 72 |
revalidatePath(BANNED_WORDS_PATH); |
... | ... | @@ -84,8 +89,8 @@ |
| 84 | 89 |
let result: ExcelUploadResult; |
| 85 | 90 |
try {
|
| 86 | 91 |
result = await uploadBannedWordExcel(file); |
| 87 |
- } catch {
|
|
| 88 |
- return { status: 'error', message: UPLOAD_FAILED_MESSAGE };
|
|
| 92 |
+ } catch (error) {
|
|
| 93 |
+ return { status: 'error', message: failureMessage(error, UPLOAD_FAILED_MESSAGE) };
|
|
| 89 | 94 |
} |
| 90 | 95 |
|
| 91 | 96 |
revalidatePath(BANNED_WORDS_PATH); |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?