"이미지를 못 보내겠으면 그거 빼고 질문만 슬쩍 보내지 마. 그림이 빠진 질문은 다른 질문이고, 틀린 질문이야."
슬그머니 내려앉는 함정
이미지 처리는 텍스트보다 실패할 데가 많아. staging 도 실패하고, 풀어내다가도 실패하고, 인코딩에서도, 업로드에서도. 이 중에 하나가 깨지면 솔깃한 '우아한' 폴백이 하나 떠올라. 뭐라도 나가게 질문만 텍스트로 보내는 거. 튼튼해 보이지. 사용자가 에러 대신 답을 받으니까. 근데 이건 트랙 3 에서 본 정직함 실패가 새 옷을 갈아입은 거야. 사용자는 이미지에 대해 물었어. 그런데 이미지가 소리 없이 빠진 질문이 배달됐고. Pippa 는 아무도 하지 않은 질문에 답한 거야. 틀린 질문에 자신만만하게 답하는 게, 맞는 질문에 정직하게 실패하는 것보다 나빠.
전부 아니면 에러
규칙은 전부 아니면 에러야. 이미지가 붙은 턴은 덩어리 전체가 배달되든가, 그러니까 질문이랑 이미지가 다 온전히 가든가. 아니면 클라이언트가 실패를 드러내고 다시 보낼 수 있게 입력 전체를 지키든가. 텍스트는 가고 이미지는 버려지는 중간 경로는 없어. 이건 트랙 2 의 통째 커밋을 그대로 비추는 거야. 질문이랑 이미지를 나눌 수 없는 한 단위로 캡처했으면 배달도 한 단위로 해야 하잖아. 반쪽 배달은 반쪽 캡처만큼 똑같이 망가뜨려.
- 성공. 질문이랑 이미지가 전부 Pippa 한테 닿음. 턴이 정직하게 답해짐.
- 에러. 이미지 경로 어딘가가 실패. 드러내고, 입력 전체를 안 날아가게 지키고, 다시 보내기를 제공. 소리 없이 버려지는 건 없음.
- 금지. 텍스트만 배달되고, 이미지는 슬그머니 사라지고, 사용자는 모름. 이 경로는 존재하면 안 됨.
에러를 내는 게 왜 더 다정한 선택인가
이미지 첨부 에러를 드러내는 건 '그냥 텍스트 보내기' 보다 덜 매끄러워 보이지만, 사용자를 존중하는 쪽이야. '이미지를 못 붙였어. 다시 해볼까?' 라고 대놓고 말해 주면 사용자가 상황을 쥐고 있게 되고 질문도 온전히 남거든. 슬그머니 텍스트만 보내는 건 그 결정을 빼앗고 등 뒤에서 의도를 망가뜨리는 거고. 정직한 오프라인이랑 똑같아. 기대고 싶은 클라이언트가 되려면, 눈에 안 보이는 그럴듯한 오답보다 눈에 보이고 되돌릴 수 있는 실패를 골라야 해. 금지된 경로를 아예 표현할 수 없게 만들어. 이미지 경로가 실패한 뒤에 텍스트를 보내는 코드 분기를 안 두는 거야. 그러면 보장이 구조로 성립해.