앱을 오래 켜 둔 뒤 세션이 만료되면 다시 로그인하는 흐름이 있었다. 로그인 자체는 성공했지만 이전 화면으로 돌아오자 목록이 비어 있거나 만료 전 요청이 오류 팝업을 띄웠다. 화면 경로만 복구하고 그 화면이 의존하는 데이터와 구독은 복구하지 않았기 때문이다.
재로그인은 처음 로그인과 비슷하지만 이미 메모리에 남은 상태가 있다는 점이 달랐다.
복구할 것과 새로 받을 것을 나눴다
사용자가 보고 있던 탭과 검색 조건은 복구할 수 있었다. 계좌 권한, 세션 연결, 거래 데이터는 새 세션에서 다시 검증해야 했다.
복구 가능 : 화면 경로, 비민감 UI 설정, 입력 중 임시 필터
재조회 : 권한, 계좌 목록, 서버 상태, 알림 구독
폐기 : 이전 요청 결과, 만료 토큰, 진행 중 주문
진행 중이던 중요한 작업은 자동 재실행하지 않고 결과를 확인하거나 사용자에게 다시 요청하도록 했다.
이전 세션 작업을 먼저 멈췄다
로그인 화면을 덮어 띄우기 전에 이전 세션의 취소 토큰을 종료하고 소켓과 주기 요청을 멈췄다. 재로그인 성공 후 새 세션 컨텍스트를 만든 뒤 구독을 다시 시작했다.
await oldSession.StopAsync();
var newSession = await auth.ReloginAsync();
await appState.InitializeForAsync(newSession);
await navigator.RestoreAsync(savedRoute);
순서를 명시하니 새 화면에 이전 응답이 들어오는 문제를 줄일 수 있었다.
복구 가능 여부를 화면이 설명했다
저장해 둔 화면 경로가 새 권한에서 접근 불가능하거나 계좌가 사라졌을 수 있었다. 그 경우 억지로 같은 화면을 열지 않고 기본 화면으로 이동해 이유를 안내했다.
복구 중에는 마지막 화면의 민감한 데이터를 그대로 보여주지 않고 안전한 로딩 상태를 사용했다. 인증이 끝나기 전에 서버 데이터가 보이지 않게 했다.
복구는 과거를 그대로 재생하는 일이 아니었다
처음에는 사용자가 있던 화면으로 돌아가면 친절한 복구라고 생각했다. 실제로는 새 세션의 사실을 기준으로 과거 의도를 다시 적용하는 과정이었다.
이 경험 뒤 재시도나 재로그인을 만들 때 이전 함수 호출을 반복하지 않는다. 무엇이 여전히 유효하고 무엇을 새로 확인해야 하는지를 나눈다. 복구의 핵심은 최대한 많이 되살리는 것보다 오래된 상태를 새 세션에 섞지 않는 데 있었다.