pharmacy-pos-qr-system/docs/TROUBLESHOOTING-CAMERA-UPLOAD.md
thug0bin 546a5e7ae6 feat: 제품 이미지 카메라 촬영 기능 추가
- HTML5 getUserMedia로 카메라 촬영 지원 (모바일 후면 카메라 기본)
- 1:1 가이드 박스 UI로 정사각형 크롭 안내
- 백엔드: PIL로 800x800 리사이즈 + 썸네일 생성
- 기존 URL 교체 기능과 탭 방식으로 통합

버그 수정:
- closeReplaceModal() 호출 전 변수 복사로 null 전송 문제 해결
- None 값 방어 코드 추가

Docs: TROUBLESHOOTING-CAMERA-UPLOAD.md 추가
2026-03-04 10:08:40 +09:00

2.4 KiB

트러블슈팅: 카메라 촬영 이미지 업로드 실패

📅 발생일: 2026-03-04

🔴 증상

  • 제품 이미지 관리 페이지에서 "촬영" 기능으로 이미지 교체 시 저장 실패
  • 에러 메시지: NoneType object has no attribute 'strip'
  • API 호출은 성공하나 이미지 데이터가 null로 전송됨

🔍 원인 분석

1차 원인: None 값 처리 누락 (백엔드)

# 문제 코드
image_data = data.get('image_data', '').strip()  # None이면 에러

# 수정 코드
image_data = (data.get('image_data') or '').strip()

2차 원인: 변수 리셋 타이밍 문제 (프론트엔드) 핵심

// 문제 코드
async function submitCapture() {
    const barcode = replaceTargetBarcode;
    const productName = replaceTargetName;
    closeReplaceModal();  // ← 여기서 capturedImageData = null 로 리셋됨!
    
    // API 호출 시 capturedImageData가 이미 null
    body: JSON.stringify({ 
        image_data: capturedImageData,  // null!
        ...
    })
}

// 수정 코드
async function submitCapture() {
    const barcode = replaceTargetBarcode;
    const productName = replaceTargetName;
    const imageData = capturedImageData;  // ← 미리 복사!
    
    closeReplaceModal();
    
    body: JSON.stringify({ 
        image_data: imageData,  // 복사된 값 사용
        ...
    })
}

3차 원인: 브라우저 캐시

  • 코드 수정 후에도 브라우저가 이전 JS를 캐시
  • Ctrl+Shift+R (강력 새로고침) 필요

해결 방법

  1. 백엔드: None 값에 대한 방어 코드 추가
  2. 프론트엔드: closeReplaceModal() 호출 전에 필요한 변수들을 로컬 변수로 복사
  3. 테스트 시: 강력 새로고침 (Ctrl+Shift+R) 또는 시크릿 모드 사용

📝 교훈

  1. 모달 닫기 함수에서 상태 리셋 주의

    • 모달을 닫으면서 관련 변수를 초기화하는 경우, async 함수에서 순서에 주의
  2. 프론트엔드 디버깅 시 브라우저 캐시 확인

    • 코드 수정 후에도 동작이 같다면 캐시 문제 의심
  3. API 직접 테스트로 문제 범위 좁히기

    • requests 또는 curl로 API만 테스트하면 프론트/백엔드 문제 구분 가능

🔧 관련 파일

  • backend/app.py - /api/admin/product-images/<barcode>/upload 엔드포인트
  • backend/templates/admin_product_images.html - 카메라 촬영 UI 및 JS