인증은 성공했지만 분석 속성을 만들다 예외가 나면 어떤 메시지를 보여줄까.
try {
const user = await signInWithProvider();
await saveSession(user.session);
await identifyAnalyticsUser(buildUserProperties(user));
navigateToHome();
} catch {
showNetworkError();
}
이 코드에서는 인증, 세션 저장, 속성 가공, SDK 호출, 화면 이동의 모든 실패가 네트워크 오류로 보인다. 요청 로그에 실패가 없어도 사용자에게 로그인 실패가 표시될 수 있다.
입력 하나를 고치기 전에 질문을 정한다. 어떤 작업의 실패가 로그인 완료를 막아야 하는가.
필수 결과와 보조 결과를 구분한다
세션 저장은 인증 이후 요청을 만들기 위한 필수 작업일 수 있다. 선택적 행동 분석은 실패해도 사용자 작업을 진행하도록 정할 수 있다. 이름이 분석이라는 이유만으로 항상 선택적인 것은 아니다. 거래·동의 증빙의 원천 기록이라면 별도의 신뢰 가능한 저장 경로가 필요하다.
이 글의 예시는 행동 분석을 보조 기능으로 정한 경우다. 인증·세션 저장의 오류 처리와 분석 실패 처리를 나눈다.
const user = await signInWithProvider();
await saveSession(user.session);
void Promise.resolve()
.then(() => identifyAnalyticsUser(buildUserProperties(user)))
.catch(error => {
try {
void Promise.resolve(
reportNonCriticalFailure("analytics_identify", error)
).catch(() => {});
} catch {
// 오류 보고의 실패가 핵심 경로로 다시 전파되지 않게 한다.
}
});
navigateToHome();
필수 작업이 완료된 뒤 분석을 별도 Promise 경계에서 시작한다. 속성 가공의 동기 throw와 SDK의 Promise 거절을 같은 보조 실패 경계로 받는다. 오류 보고도 동기·비동기 실패가 새 미처리 오류를 만들지 않게 보호한다. Promise.then 동작에 따르면 콜백에서 던진 예외는 반환 Promise를 거절한다.
핵심 경로의 인증·세션 오류 처리는 별도로 유지한다. 위 호출들은 기존 어댑터를 가정한 경계 예시이며 전체 로그인 구현은 아니다. navigation은 분석 완료를 기다리지 않아 앱 종료나 페이지 전환에서 이벤트가 유실될 수 있다. 반드시 전달돼야 할 기록에는 이 방식을 쓰지 않는다.
그림의 분리는 오류를 없애는 것이 아니라 전파 방향을 제한한다. 로그인 성공과 분석 수집 성공은 각각 관측한다.
입력 검증도 별도로 남긴다
function birthYear(value: unknown): string | undefined {
if (typeof value !== "string") return undefined;
const normalized = value.trim();
if (!/^\d{4}-\d{2}-\d{2}$/.test(normalized)) return undefined;
return normalized.slice(0, 4);
}
이 함수는 문자열 형태를 제한한다. 실제 달력 날짜가 유효한지까지 검증하지 않으므로 필요한 경우 추가 규칙을 둔다. 분석에 생년월일 원문이 필요한지도 따로 결정한다.
빈 값 예외를 고쳐도 SDK 초기화·오프라인·전송 실패는 남을 수 있다. 입력 검증과 실패 격리를 함께 사용한다. 실제 제공자의 속성·전송 계약은 해당 SDK 버전의 공식 문서로 확인한다.
각 실패에서 달라져야 할 결과를 검사한다
분석 어댑터가 동기 예외, Promise 거절, 끝나지 않는 대기를 만들 때 필수 작업과 이동이 유지되는지 검사한다. 오류 보고 함수가 실패하는 경우도 포함한다. 반대로 인증·세션 저장 실패를 정상 이동으로 숨기지 않는지 확인한다.
관측 단계는 auth_provider, session_store, analytics_identify, navigation처럼 나누고 토큰·개인 속성 전체를 덤프하지 않는다. 분석 호출이 끝났다는 사실과 실제 수집됐다는 사실도 구분한다.
이 경계는 보조 기능을 기다리지 않는 것이 허용될 때 유효하다. 다음 판단은 오류 메시지를 바꾸는 데 두지 않고 필수 결과를 유지하면서 분석 실패를 운영자가 알아볼 수 있는지에 둔다.
