본문 바로가기

IT 지식창고

저장 완료 로그를 믿었다가 본문이 그대로 남은 사고

728x90
반응형

블로그를 브라우저로 자동 조작해 발행하는 도구를 만들고 있습니다. 어느 날 이미 올라간 글 하나의 제목만 바꾸려고 스크립트를 돌렸는데, 로그에는 분명 "저장 완료"가 찍혔습니다. 그런데 다시 열어보니 제목은 바뀌어 있고 본문은 예전 그대로였습니다. 오류 하나 없이 절반만 저장된 셈입니다. 그날 겪은 일과 원인을 찾아간 과정을 적어둡니다.

한눈에 보기

  • 이미 발행된 글의 제목을 바꾸는 스크립트를 돌렸는데 제목만 바뀌고 본문은 예전 그대로 저장됐습니다
  • 오류 로그는 없었습니다. "저장 완료"까지 정상적으로 찍혔습니다
  • 원인은 에디터가 화면에 보여주는 내용과 실제로 서버에 저장되는 내용이 다른 상태였다는 것입니다
  • 사람이 타이핑할 때만 켜지는 내부 신호를 스크립트가 건너뛰고 있었습니다
  • 지금은 저장 전후로 본문 글자 수를 직접 대조해서, 로그가 아니라 결과로 확인합니다

무슨 일이 있었나요

작업은 단순했습니다. 이미 발행된 글의 제목만 새 문구로 바꾸는 스크립트였습니다. 본문에는 손대지 않는 작업이라 오히려 안전하다고 생각했습니다. 제목 입력창에 새 텍스트를 채우고, 에디터의 내용을 확인하는 함수로 본문이 그대로 있는지 읽어봤습니다. 읽어온 값은 분명 원래 본문이었습니다. 저장 버튼을 누르고 "저장 완료" 로그를 확인한 뒤 다음 글로 넘어갔습니다.

문제는 나중에 그 글을 사람이 열어봤을 때 드러났습니다. 제목은 새 문구로 바뀌어 있었는데, 본문은 스크립트가 실행되기 전의 옛날 내용 그대로였습니다. 로그만 봐서는 무엇이 잘못됐는지 전혀 알 수 없었습니다. 에러도, 경고도 없이 딱 절반만 저장된 상태였습니다.

왜 이런 일이 일어났나요

먼저 의심한 것은 "읽어온 본문이 사실은 옛날 값이었나"였습니다. 확인해보니 아니었습니다. 스크립트가 에디터에서 읽어온 값은 분명 최신 본문이었습니다. 그런데 저장하고 다시 열면 그 값이 반영되지 않았습니다.

여기서 실마리를 찾았습니다. 이 에디터는 화면에 보여주는 모델과 실제로 저장되는 상태가 분리돼 있었습니다. 화면에 그려진 내용을 읽는 함수는 정상 작동했지만, 그 값을 서버에 전달하는 통로는 사람이 직접 타이핑할 때만 열리는 신호로 갱신되는 구조였습니다. 스크립트가 값을 프로그램으로 직접 밀어 넣으면, 화면에는 보이지만 저장 통로로는 전달되지 않는 상태가 만들어진 것입니다.

사람이 키보드를 두드릴 때는 브라우저가 change, input 같은 이벤트를 자동으로 발생시킵니다. 에디터는 이 이벤트를 신호 삼아 "지금 내용이 바뀌었다"고 판단하고 내부 상태를 다시 채웁니다. 그런데 스크립트로 값만 바꾸면 이 이벤트가 발생하지 않습니다. 화면은 새 내용을 보여주지만, 에디터 입장에서는 "아무 일도 없었다"고 인식하는 것입니다.

입력 방식 change·input 이벤트 에디터 내부 상태
사람이 타이핑 자동 발생 즉시 갱신
스크립트가 값만 대입 발생하지 않음 갱신 안 됨
1. 스크립트가 에디터 내용을 직접 덮어씀   → 화면엔 새 본문이 보임
2. change·input 이벤트가 발생하지 않음    → 에디터 내부 상태는 그대로
3. 저장 버튼을 누름                      → 에디터 내부 상태(옛 본문)가 전송됨
4. "저장 완료" 로그 출력                 → 그러나 실제로 저장된 건 옛 본문

어떻게 고쳤나요

해결 방법은 사람이 입력한 것처럼 신호를 만들어주는 것이었습니다. 에디터가 제공하는 내부 저장 함수를 먼저 호출해 화면 내용을 아래 텍스트 영역에 내려쓰고, 그 다음 changeinput 이벤트를 코드로 직접 발생시켰습니다.

// 화면 내용을 내부 textarea 로 내려쓴다
editor.save();

// 사람이 입력한 것처럼 신호를 준다
textarea.dispatchEvent(new Event('change', { bubbles: true }));
textarea.dispatchEvent(new Event('input', { bubbles: true }));

이 세 줄을 저장 버튼을 누르기 직전에 추가하자 본문이 정상적으로 갱신됐습니다. 제목보다 본문을 먼저 채우는 순서도 함께 바꿨습니다. 반대 순서로 하면 제목만 저장되는 현상이 재현됐기 때문입니다.

그 뒤로 무엇이 달라졌나요

가장 크게 바꾼 것은 "저장 완료" 로그를 더는 성공의 증거로 보지 않기로 한 것입니다. 지금은 저장하기 전에 원본 본문의 글자 수를 세어두고, 저장한 뒤 그 글을 다시 열어 글자 수가 같은지 대조합니다. 숫자가 다르면 그 자리에서 작업을 멈춥니다.

로그는 스크립트가 "무엇을 시도했는지"만 말해줍니다. 실제로 무엇이 저장됐는지는 다시 열어서 확인하기 전까지는 알 수 없다는 걸 이번 일로 배웠습니다.

비슷한 자동화를 만든다면

브라우저를 코드로 조작해 무언가를 저장하는 도구를 만든다면, 같은 함정에 빠지기 쉬운 지점이 있습니다.

값을 프로그램으로 직접 채우는 에디터·폼일수록 "화면에 보이는 것"과 "실제로 전송되는 것"이 다를 수 있다는 걸 염두에 두는 편이 안전합니다.

정리하면

  • 오류 없는 로그가 항상 성공을 의미하지는 않습니다. "저장 완료"는 시도했다는 뜻이지 결과를 보장하지 않습니다
  • 이 에디터는 화면 모델과 저장 상태가 분리돼 있었고, 사람이 입력할 때만 발생하는 이벤트로 저장 상태가 갱신됐습니다
  • change·input 이벤트를 코드로 직접 발생시켜 사람이 입력한 것처럼 신호를 주면 해결됩니다
  • 지금은 저장 전후 글자 수를 대조해 로그가 아니라 실제 결과로 성공 여부를 판단합니다
반응형