Cheondi
개발 · Unity

문구 하나가 빠졌는데 화면 전체가 멈췄다

다국어 문자열 누락이 화면 초기화 실패로 번진 문제를 안전한 조회와 검증으로 막은 기록입니다.

  • #localization
  • #defensive-code
  • #unity

새 화면을 열면 아무것도 나타나지 않는 문제가 있었다. 레이아웃이나 API를 먼저 의심했지만 초기화 중 다국어 문구 키 하나를 찾지 못해 예외가 발생하고 있었다. 버튼 설명 하나가 없다는 이유로 목록과 이벤트 연결까지 실행되지 않았다.

문자열 데이터는 화면의 부가 요소라고 생각했는데 초기화 흐름에서는 필수 의존성이었다. 누락됐을 때 어느 수준까지 계속 동작할지 정해야 했다.

조회 실패를 화면 전체 실패로 만들지 않았다

인덱서로 바로 읽던 코드를 안전한 조회 함수로 감쌌다.

string Text(string key)
{
    if (strings.TryGetValue(key, out var value) &&
        !string.IsNullOrWhiteSpace(value))
        return value;

    Log.Warn($"localization.missing key={key}");
    return $"[{key}]";
}

개발 환경에서는 누락이 눈에 보이도록 키를 표시하고, 사용자 환경에서는 기준 언어 문구로 대체하는 정책을 둘 수 있었다.

로드와 사용 사이를 검증했다

JSON 파싱이 성공해도 필요한 키가 전부 있다는 뜻은 아니었다. 앱 시작이나 빌드 검증 단계에서 화면별 필수 키 목록과 언어 파일을 비교했다.

기준 언어 키 집합 - 대상 언어 키 집합 = 누락 키
대상 언어 키 집합 - 기준 언어 키 집합 = 사용되지 않는 후보

공백 값과 형식 자리표시자 개수도 확인했다. {0}이 필요한 문구에서 자리표시자가 사라지면 실행 중 포맷 오류가 날 수 있었다.

실패 범위를 작게 만들었다

문구 하나를 설정하는 코드가 화면의 핵심 데이터 로드 앞에 있었기 때문에 예외 영향이 컸다. UI 라벨 설정과 데이터 요청을 분리하고, 부가 문구 오류가 핵심 기능 초기화를 막지 않게 했다.

그렇다고 모든 예외를 삼키진 않았다. 어떤 키와 언어에서 대체가 발생했는지 집계해 배포 전에 찾을 수 있게 했다.

새 화면을 추가할 때는 기준 언어 키를 먼저 등록하고 다른 언어의 누락 목록을 생성했다. 번역이 아직 준비되지 않은 경우에도 어떤 기본 문구가 사용되는지 리뷰에서 확인할 수 있게 했다. 런타임 방어와 배포 전 검사는 서로 다른 역할이었다.

정적 데이터도 계약이었다

API 응답에는 필드 누락을 걱정하면서 다국어 파일은 늘 완전할 거라고 가정했다. 실제로는 둘 다 생산자와 소비자 사이의 계약이었다. 키 이름, 필수 여부, 기본값이 필요했다.

문구 누락 한 건을 고친 뒤 번역 파일 변경도 코드 변경처럼 검증하게 됐다. 사용자가 읽는 텍스트는 장식이 아니라 화면이 의존하는 데이터였다.