파트너 정산 은행 자동화 UI 감지 로직 개선과 에러 분류
목차
파트너 정산 자동화를 손보러 들어갔다가 예상보다 훨씬 깊이 파고들었던 작업. 처음엔 "셀렉터 몇 개 고치면 끝나겠지"였는데, 막상 열어보니 감지 로직 설계 자체에 문제가 있었음.
특정 은행 웹 자동화 핸들러였는데, 기존 코드는 페이지 진입 후 고정 selector 하나로 "직접받기" 버튼을 찾는 구조였다. 상대 사이트가 UI를 살짝 바꾸면서 버튼이 여러 형태로 나타나기 시작했고, 그 중 케이스 A(모달 직접 노출)만 전제로 짜여 있던 로직이 B/C 상황에서 연달아 터진 거였음.
실제로 발생하던 케이스는 세 가지였다.
- 케이스 A: 모달 안에 버튼이 바로 노출되는 정상 흐름
- 케이스 B: 본인인증 단계가 한 번 더 끼면서 버튼 위치가 밀리는 경우
- 케이스 C: 점검 배너가 떠서 버튼 자체가 비활성화된 경우
케이스 B에서는 null 참조가 터졌고, C에서는 자동화가 무한 대기에 빠졌다. 그 사이 운영 알람만 시끄럽게 울리고, 정작 어디서 깨졌는지 추적하기 어려운 상황이 반복됐음.
외부 사이트 자동화가 유독 깨지기 쉬운 이유
내부 시스템 자동화와 달리, 외부 사이트를 긁는 자동화는 근본적으로 계약이 없는 인터페이스를 다룬다. 우리 쪽 코드를 한 줄도 안 건드려도, 상대방이 HTML 구조를 바꾸거나 점검을 걸면 즉시 깨진다. 그러다 보니 "이 셀렉터가 언제나 존재한다"는 가정 자체가 리스크가 됨.
문제는 대부분의 자동화 코드가 처음 만들 때 "잘 되는 케이스"만 보고 짜인다는 것. 정상 흐름을 구현하고 나면 일단 동작하니까 넘어가는데, 그게 쌓이면 나중에 낯선 상황 하나가 끼었을 때 어디서 깨졌는지 전혀 파악이 안 되는 구조가 된다. 이번 케이스가 딱 그랬음.
셀렉터 교체로 해결되는 문제가 아니라는 걸 파악하고 나서, 세 가지를 동시에 건드렸다.
| 변경 항목 | 이전 | 이후 |
|---|---|---|
| UI 감지 | 단일 selector | 다중 후보 + 우선순위 |
| 버튼 클릭 | 즉시 click | visible + enabled 확인 후 click |
| 점검 페이지 | 미처리 | 사전 감지 후 즉시 fail-fast |
UI 감지 로직은 후보 셀렉터를 순서대로 시도하는 방식으로 바꿨고, 클릭 전에 버튼이 실제로 보이고 활성화된 상태인지 확인하는 단계를 추가했다. 점검 배너 감지는 아예 가장 앞단으로 뽑아서, 배너가 떠있으면 나머지 로직을 탈 것도 없이 즉시 종료하도록 했다.
실행 흐름을 정리하면 이렇다.
1. 페이지 로드 대기
2. 점검 배너 감지 → 있으면 즉시 종료 (SITE_MAINTENANCE)
3. UI 변종 A/B 둘 다 시도 (우선순위 순)
4. 클릭 가능 상태 체크 후 액션
5. 실패 시 스크린샷 저장 + 에러 코드 분리
에러 분류가 핵심이었다
이번 작업에서 체감 개선이 가장 컸던 건 에러 코드 분리였다. 기존엔 모든 실패가 "자동화 오류" 한 종류로 뭉개져 있었음. 그러다 보니 알람이 와도 로그를 직접 열어서 스택 트레이스를 읽어야 원인을 파악할 수 있었고, 보는 사람에 따라 해석이 달랐다.
이번에 UI_CHANGED / SITE_MAINTENANCE / AUTH_EXPIRED 세 코드로 쪼갰는데, 반응이 바로 왔음. 운영팀 입장에서 SITE_MAINTENANCE가 떴을 땐 "은행 점검 끝날 때까지 기다리면 됨"이고, AUTH_EXPIRED가 떴을 땐 "인증 세션 갱신이 필요함"이고, UI_CHANGED가 떴을 땐 "개발팀에 셀렉터 업데이트 요청"이다. 에러 코드 하나로 다음 행동이 결정되는 구조.
여기서 트레이드오프가 하나 있긴 하다. 에러를 세분화할수록 분류 기준을 코드로 유지해야 하고, 그 분류가 틀리면 오히려 혼란을 준다. UI_CHANGED인데 AUTH_EXPIRED로 분류되면 엉뚱한 팀이 대응하러 달려가는 상황이 생기니까. 초기에 분류 기준을 문서화해두고, 실제 사례가 쌓이면 기준을 조정하는 사이클이 필요하다.
실패 시점 스크린샷 저장도 같이 붙였는데, 처음엔 저장 경로 설정이 귀찮아서 나중에 하려 했었음. 작업 끝내고 며칠 뒤에 실제 장애가 한 건 발생했는데, 스크린샷이 있으니까 5분 만에 원인 파악이 됐다. 안 붙였으면 로그만 보면서 한참 헤맸을 것.
무한 대기가 에러보다 나쁘다
자동화에서 가장 위험한 건 "에러"가 아니라 "조용한 실패"라는 걸 이번에 다시 체감했다. 예외가 터지면 알람이라도 오는데, 무한 대기는 프로세스가 멀쩡해 보이는 채로 아무 일도 안 하고 있다. 모니터링 입장에서는 정상이고, 실제로는 정산이 다 멈춰있는 상태.
빨리 죽는 게 낫다는 원칙, 외부 자동화에서는 특히 명확하게 적용된다. 뭔가 예상과 다른 상황이 감지됐을 때 명시적으로 실패하고, 원인을 남기고, 알리는 쪽이 무한 재시도나 묵묵한 대기보다 훨씬 나은 설계다.
남은 숙제가 하나 있다. 점검 케이스를 메신저로 별도 분기해서 운영팀이 즉시 인지하도록 하는 작업. 현재는 에러 코드가 분류되긴 하는데 알림 채널이 통합되어 있어서, SITE_MAINTENANCE 가 다른 에러들에 묻히는 경우가 있음. 분기 처리하면 점검 중 불필요한 재시도도 줄일 수 있어서 곧 붙일 예정.
자동화는 결국 "실패를 잘 알리는 것"이 절반 이상이라는 결론. 동작 로직보다 실패 처리에 더 공들여야 한다는 걸 매번 배우고 매번 다시 배운다.
댓글 0
첫 댓글 달아줘.