Skip to content
isdnetworks
Go back

넓힌 catch가 여는 안쪽

작업 실패 처리에서 일부 오류가 안 잡히고 있었다. 예외 계열만 잡고 오류 계열은 빠져나가는 구조라 잡는 범위를 최상위 인터페이스로 넓히면 되겠다는 계획을 세웠고 검토를 받았다.

Table of contents

Open Table of contents

통째로 열리는 안쪽

1차 검토를 반영해 다시 쓴 계획서를 2차로 검증하면서 새 차단 사유가 셋 나왔다. 첫째는 실패 처리 함수가 무엇을 하는지였다.

그 함수가 특정 채널이면 라이브 HTTP 조회를 하고 결과를 가드 없이 쓰고 있었다. 지금은 오류 계열이 거기까지 안 오지만 범위를 넓히면 오게 되므로 한 줄짜리 패치로 그 오염 경로가 통째로 열리고 상태가 이미 이상한 상황에서 외부 조회와 쓰기가 일어난다.

여기서 규칙이 나왔는데 잡는 범위를 넓히는 패치는 그 블록 안에서 새로 실행되기 시작하는 하위 호출까지 추적해야 한다는 것이다. 기존에는 그 상황에서 프로세스가 죽었고 이제는 그 블록이 돌기 시작하므로 안에 무엇이 있는지를 봐야 한다.

진단을 막는 진단 코드

둘째는 진단 메시지였다. 사람이 읽을 메시지를 만들려고 식별자를 인코딩하는 함수를 부르는데 그 대상이 삭제 처리가 만드는 합성 레코드였다.

합성 레코드의 상품 식별자가 비어 있고 인코딩 함수가 숫자가 아닌 값을 받으면 예외를 던진다. 진단 메시지를 만들다가 예외가 나서 의도한 메시지는 생성 도중에 죽고 로그에 아무것도 안 남는다.

패치가 재현한 원래 증상

셋째가 가장 나빴다. 건너뛴 건수를 세려고 카운터를 올리는데 그 프로퍼티가 선언돼 있지 않았다.

이 프로젝트는 미선언 프로퍼티 접근 알림을 예외로 승격시키고 그 줄이 이미 실행 중인 블록 안에 있으므로 그 블록이 자기 예외를 못 잡는다. 예외가 그대로 탈출해 커맨드 전체가 죽는데 원래 고치려던 증상을 패치 코드 자신이 재현하는 형태였다.

무방비인 블록 안

이것이 핵심이었다. 예외를 잡는 블록 안에서 난 예외는 그 블록이 못 잡는다.

그 안은 안전한 곳이 아니라 오히려 잡아 줄 사람이 없는 자리다. 그래서 그 안에는 예외가 날 수 있는 코드를 넣지 않고 넣어야 하면 또 감싸며 카운터나 로깅 같은 것도 확인해야 한다.

다시 검증한 계획서

이 셋이 2차 검토에서 나왔다는 점이 남는다. 1차에서 나온 것을 반영해 다시 쓴 계획서를 다시 검증한 것이다.

같은 계획서를 두 번 본 것이 아니라 고친 계획서를 본 것이고 고치면 새 코드가 들어가며 새 코드에는 새 문제가 있을 수 있다. 수정이 새 문제를 만든다는 것을 세 번째 사유가 그대로 보여 줬다.

정리


Share this post on:

Previous Post
기간 없는 미처리 집계의 과대
Next Post
고급 기능의 도입 시점