임동욱 임동욱 08-27
feat: 가맹점 저장 실패를 토스트로 알린다
폼 맨 아래 FoxHelperText에 있던 문구를 토스트로 올린다 — 등록 폼이 길어서 스크롤 밖에
있으면 저장이 왜 안 됐는지 보이지 않았다. 칸별 오류는 해당 입력칸에 그대로 둔다.

메시지도 백엔드 사유를 그대로 쓴다(형제 화면의 failureMessage와 같은 방식) — 고정 문구는
"저장하지 못했습니다"밖에 알려 주지 못했다.

Co-Authored-By: Claude Opus 5 
@659034ff7bcb94d2f6ad087843743a7163b47f3f
app/(protected)/(basic)/system/merchants/_actions.ts
--- app/(protected)/(basic)/system/merchants/_actions.ts
+++ app/(protected)/(basic)/system/merchants/_actions.ts
@@ -3,6 +3,7 @@
 import { unstable_rethrow } from 'next/navigation';
 import { revalidatePath } from 'next/cache';
 import { verifySession } from '@/lib/auth/dal';
+import { BackendRequestError } from '@/lib/http/backend-fetch';
 import { createMerchant } from '@/lib/data/repositories/merchant-repository';
 import {
   validateMerchant,
@@ -11,6 +12,10 @@
 import { MERCHANTS_PATH } from '@/lib/domain/merchant-query';
 
 const SAVE_FAILED_MESSAGE = '저장하지 못했습니다. 잠시 후 다시 시도해 주세요.';
+
+function failureMessage(error: unknown, fallback: string): string {
+  return error instanceof BackendRequestError ? error.message : fallback;
+}
 
 function readString(formData: FormData, key: string): string {
   const value = formData.get(key);
@@ -49,7 +54,7 @@
   } catch (error) {
     // 이슈: 세션이 밀렸을 때 backendFetch가 던지는 redirect를 이 catch가 삼키면 안 된다.
     unstable_rethrow(error);
-    return { status: 'error', message: SAVE_FAILED_MESSAGE };
+    return { status: 'error', message: failureMessage(error, SAVE_FAILED_MESSAGE) };
   }
 
   revalidatePath(MERCHANTS_PATH);
app/(protected)/(basic)/system/merchants/_components/merchant-form-modal.tsx
--- app/(protected)/(basic)/system/merchants/_components/merchant-form-modal.tsx
+++ app/(protected)/(basic)/system/merchants/_components/merchant-form-modal.tsx
@@ -64,6 +64,13 @@
         message: isEdit ? '가맹점을 수정했습니다.' : '가맹점을 등록했습니다.',
       });
       onClose();
+      return;
+    }
+
+    // 칸별 오류는 해당 입력칸에 그대로 두고, 폼 전체에 걸린 사유만 토스트로 알린다 —
+    // 긴 폼이라 맨 아래 문구는 스크롤 밖에 있으면 보이지 않는다.
+    if (state.status === 'error' && state.message) {
+      showToast({ variant: 'danger', message: state.message });
     }
   }, [state, showToast, onClose, isEdit]);
 
@@ -325,10 +332,6 @@
               />
             </div>
           </div>
-        )}
-
-        {state.status === 'error' && state.message && (
-          <FoxHelperText type="danger" message={state.message} />
         )}
       </form>
     </FoxModal>
Add a comment
List