해결 : 에러 메세지를 직접적으로 보이지 않게 처리
“Failed to execute ‘json’ on ‘Response’: Unexpected end of JSON input”은 프론트엔드에서 fetch로 받은 응답(response)을 JSON으로 파싱하려 했는데, 백엔드가 비어 있는 응답을 보냈기 때문

if (!response.ok) {
const data = await response.json(); // ← 문제 발생 가능 지점
throw new Error(data.detail || '회원가입에 실패했습니다.');
}
response.ok가 false일 때
→ FastAPI가 빈 응답(내용이 없음) 을 보내면
→ await response.json() 이 JSON으로 파싱할 데이터가 없어서 Unexpected end of JSON input 에러
if (!response.ok) {
let data;
try {
// 응답이 JSON 형식인지 확인
data = await response.json();
} catch {
// 비어 있거나 JSON이 아닐 경우 대비
data = {};
}
throw new Error(data.detail || '회원가입에 실패했습니다.');
}
crud.create_user() 함수는 db_user — 즉 SQLAlchemy 모델 객체(models.User) 를 그대로 반환
def create_user(db: Session, user:
schemas.UserCreate, hashed_password: str):
db_user = models.User(
username=user.username,
name=user.name,
hashed_password=hashed_password
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
models.User 는 Python 객체(ORM 객체)이지 JSON 직렬화 불가능한 타입
FastAPI는 response_model=schemas.User 덕분에 자동 변환을 시도하지만, 그게 실패하거나 빈 응답으로 처리되면 프론트엔드에서는 Unexpected end of JSON input !
@router.post("/signup", response_model=schemas.User)
def signup(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_username(db, username=user.username)
if db_user:
raise HTTPException(status_code=400, detail="Username already registered")
hashed_password = get_password_hash(user.password)
created_user = crud.create_user(db=db, user=user, hashed_password=hashed_password)
# ORM → Pydantic 변환
return schemas.User.from_orm(created_user)