HKUDS/DeepTutor · error · HTTPException

str(exc)

Error message

str(exc)

What it means

Generic 500 raised by the create_book endpoint when BookEngine.create_book throws an unexpected (non-ValueError) exception. The raw exception string is echoed to the client and the full traceback is logged server-side. It is a catch-all, so the underlying cause can be anything from LLM provider failures to document parsing errors inside the engine.

Source

Thrown at deeptutor/api/routers/book.py:539

    """Stage 1: capture inputs + run IdeationAgent."""
    if not req.user_intent.strip():
        raise HTTPException(status_code=400, detail="user_intent is required")
    engine = get_book_engine()
    try:
        book, proposal = await engine.create_book(
            user_intent=req.user_intent,
            chat_session_id=req.chat_session_id,
            chat_selections=req.chat_selections,
            notebook_refs=req.notebook_refs,
            knowledge_bases=req.knowledge_bases,
            question_categories=req.question_categories,
            question_entries=req.question_entries,
            language=req.language,
            depth=req.depth,
        )
    except Exception as exc:  # noqa: BLE001
        logger.error(f"create_book failed: {exc}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(exc))
    return {
        "book": book.model_dump(mode="json"),
        "proposal": proposal.model_dump(mode="json"),
    }


@router.post("/books/confirm-proposal")
async def confirm_proposal(req: ConfirmProposalRequest) -> dict[str, Any]:
    """Stage 2: user confirms (and possibly edits) the proposal → SpineAgent."""
    engine = get_book_engine()
    edited: BookProposal | None = None
    if req.proposal:
        try:
            edited = BookProposal.model_validate(req.proposal)
        except Exception as exc:
            raise HTTPException(status_code=400, detail=f"Invalid proposal: {exc}")
    try:
        book, spine = await engine.confirm_proposal(book_id=req.book_id, edited_proposal=edited)

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Check server logs — logger.error(..., exc_info=True) prints the full traceback that explains the real cause
  2. Verify LLM provider config (API key, base URL, model name) is set in data/user/settings or env
  3. Re-run the request with a simpler topic to rule out content/parsing issues
  4. If the traceback points inside deeptutor, file/report it with the stack trace instead of retrying blindly

Example fix

// before
raise HTTPException(status_code=500, detail=str(exc))
// after (safer detail)
raise HTTPException(status_code=500, detail="Book creation failed; see server logs") from exc
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const res = await fetch('/books/create', {...});
  if (res.status === 500) { const e = await res.json(); console.error(e.detail); /* check server logs */ }
} catch (netErr) { /* transport error */ }

Prevention

When it happens

Trigger: POST /api/books/create with a valid request schema where the engine fails downstream: unreachable LLM provider, missing API key, RAG/KB lookup failure, or a bug in proposal generation. Any exception other than ValueError from engine.create_book.

Common situations: Missing OPENAI/LLM API key in env, provider rate-limit or timeout during proposal generation, malformed source documents, or version mismatch between router and engine after a partial upgrade.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/58740c86476ff2d2. Report an issue: GitHub.