프로젝트 / 베리모어 개발

버그와의 전쟁

2026.02.14 3분 읽기

버그와의 전쟁 — JOIN 중복부터 외래키까지

2025년 11월 1일 ~ 2일 · v1.3 → v1.4

이틀 연속으로 버그와 싸웠다. 첫째 날은 에셋 중복 표시 버그에 하루 종일 매달렸고, 둘째 날은 텍스트 블록 500 에러를 잡았다. 짧지만 강렬한 이틀이었다.

에셋 중복 버그 — 5번의 시도, 1번의 승리

프로젝트 에디터에서 에셋 목록을 불러오면, ID 86번이 두 번 표시되고 ID 82번은 빠져 있었다. DB에는 10개인데 API가 11개를 반환하는 상황. 원인은 project_assetscharacter_assets를 INNER JOIN으로 엮는 복잡한 쿼리에서 1:N 관계로 행이 뻥튀기되고 있었다.

  1. 1차 — PHP in_array 중복 제거 → 실패
  2. 2차 — isset 키 기반 제거 → 실패
  3. 3차 — SQL DISTINCT → 실패
  4. 4차 — 서브쿼리 분리 → 실패
  5. 5차 — API 전면 재작성 → 성공!

복잡한 INNER JOIN을 버리고, 두 개의 단순한 SELECT 쿼리 + PHP 배열 매핑 방식으로 완전히 다시 썼다. 결과는 완벽. 중복 없이 정확히 10개의 에셋이 반환됐다.

"DB에는 문제가 없다는 거 너도 알지? 그러면 네가 제어할 수 있는 코드에서 모든 문제가 생긴거야."

텍스트 블록 500 에러 — 외래키의 교훈

다음 날, 텍스트 블록을 저장하면 500 Internal Server Error가 발생했다. 이미지 블록은 잘 되는데 텍스트만 에러. 원인은 의외로 간단했다.

portfolio_blocks.block_typeblock_types.type_name을 외래키로 참조하는데, block_types 테이블에 'text' 타입이 등록되어 있지 않았다.

INSERT INTO block_types (type_name, type_label, description, is_active)
VALUES ('text', '텍스트', '리치 텍스트 에디터 블록', 1);

한 줄로 해결됐다. 500 에러의 원인이 코드가 아니라 데이터 누락이었다는 점이 이 이틀의 반전.

교훈: 같은 방법을 반복하지 말고, 세 번 이상 실패하면 접근 방식 자체를 전환할 것. 새로운 블록 타입을 추가할 때는 코드를 짜기 전에 반드시 DB의 block_types 테이블에 먼저 등록할 것.

베리모어 개발 글 목록

← 프로젝트로 이동
프로젝트 완료 2026.02.15 GOC크리에이터 배너 추가 2026.02.15 사용자 기능 업데이트 2026.02.15 콘텐츠 경험 2026.02.15 안정화와 디자인 개편 2026.02.15 베타 완성 2026.02.15 디자인 수정 2026.02.15 버그와의 전쟁 2026.02.14 첫 발을 내딛다 2026.02.14