사이드프로젝트 slecs

송금 폼 버그 6건을 이벤트 누락 하나로 한 번에 해결

목차

송금 폼 6건 한 번에 잡은 날

특정 시중은행 연동 송금 폼에서 자잘한 버그 6건이 동시에 올라옴. 하나씩 보면 사소한데 모이니까 사용자가 1단계도 못 넘는 상황. 결제 플랫폼에서 "입력 안 됨"은 곧 이탈이라 우선순위 최상위로 올림.

증상 정리

올라온 리포트 그대로 옮기면:

번호 증상 재현 조건
1 금액 입력 시 콤마 두 번 찍힘 IME 한글 → 숫자 전환 직후
2 계좌번호 붙여넣기하면 하이픈 남음 클립보드 경유
3 받는분 이름 공백 trim 안 됨 끝에 스페이스
4 메모 한글 길이 초과 검증 누락 20자 넘는 한글
5 뒤로가기 시 입력값 유실 단계 이동 후 복귀
6 제출 버튼 더블클릭 시 중복 요청 네트워크 느릴 때

전부 "포커스/이벤트/상태" 셋 중 하나에 묶임. 백엔드 로직 문제가 아니라 폼 상태기계가 뭉개진 거였음.

원인 한 문장 요약

  • 1·2번: 입력 정규화 함수가 change 이벤트에서만 돌고 input에서 안 돌아서 IME/붙여넣기 케이스 누락.
  • 3·4번: 서버 검증은 있는데 클라 검증이 빠져서 1라운드 트립 낭비.
  • 5번: 단계 이동을 라우터로 처리하면서 폼 상태를 세션에 안 올림.
  • 6번: 제출 버튼 disabled 토글이 응답 도착 후라 race 발생.

원인 나열하니 공통 패턴은 "이벤트 1개에만 의존". 사용자 입력 경로는 키보드, IME, 클립보드, 음성, 자동완성 다섯 갈래라는 걸 또 까먹음.

수정 방향

// before
input.addEventListener('change', normalize)

// after
['input', 'change', 'blur', 'paste'].forEach(ev =>
  input.addEventListener(ev, normalize)
)
  • 정규화는 멱등 함수로 만들어서 몇 번 호출돼도 결과 동일하게.
  • 제출 버튼은 클릭 즉시 disabled, 응답/에러/타임아웃 셋 다 핸들러에서 풀기.
  • 단계 이동은 임시 키로 폼 스냅샷 저장, 복귀 시 hydrate.

회고

  • 폼 버그는 단위 테스트로 잘 안 잡힘. 손으로 한 번 따라 쳐보는 게 빠름.
  • "사소한 6건"으로 묶여 들어왔지만 원인 분석하니 상태기계 설계 부재라는 한 가지 문제. 다음엔 폼 만들 때 이벤트 매트릭스부터 그리고 시작.
  • 회귀 방지용으로 IME/붙여넣기/더블클릭 시나리오를 e2e에 박아둠. 같은 패턴 또 올라오면 그때 컴포넌트 분리 검토.

다음

댓글 0

첫 댓글 달아줘.