datawhalechina/hello-agents · error · HTTPException

str(e)

Error message

str(e)

What it means

A catch-all `except Exception as e` at the end of a FastAPI chat endpoint re-raises every failure as `HTTPException(status_code=500, detail=str(e))`. The 'message' is therefore not a fixed string but the repr/text of whatever underlying exception escaped the agent-run pipeline (LLM API error, KeyError on message roles, JSON serialization of tool_calls, etc.). It surfaces raw internal exception text to the HTTP client.

Source

Thrown at Co-creation-projects/angelen-SoftwareDevHelper/src/main.py:195

                            "name": getattr(func, "name", ""),
                            "arguments": args,
                            "result": "" # 稍后填充
                        })
            # 查找 tool 角色的消息(工具执行结果)
            elif msg.role == "tool":
                tool_call_id = getattr(msg, "tool_call_id", None)
                if tool_call_id:
                    for tc_info in tool_calls_info:
                        if tc_info["id"] == tool_call_id:
                            tc_info["result"] = msg.content
                            break

        # 保存助手消息(同时保存工具调用信息)
        save_session_history(session_id, title, response, False, tool_calls=tool_calls_info)

        return {"response": response, "session_id": session_id, "tool_calls": tool_calls_info}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/api/upload_project")
async def upload_project(session_id: str = Form(...), file: UploadFile = File(...)):
    if not file.filename.endswith('.zip'):
        raise HTTPException(status_code=400, detail="只接受 .zip 格式的压缩包")

    upload_dir = os.path.join(os.path.dirname(__file__), "../outputs/uploads")
    os.makedirs(upload_dir, exist_ok=True)
    
    file_id = str(uuid.uuid4())
    file_path = os.path.join(upload_dir, f"{file_id}_{file.filename}")
    
    try:
        with open(file_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
            
        agent = get_or_create_agent(session_id)
        

View on GitHub (pinned to 606a07d341)

Solutions

  1. Reproduce with the same request and read the server console/traceback: `detail=str(e)` only echoes the inner exception, so the true cause is the original traceback, not the 500 body.
  2. Verify LLM env vars (API key, base URL, model name) are set in the environment the server was started in.
  3. Check that `response` and `tool_calls_info` contain only JSON-serializable values before `save_session_history`.
  4. Replace the blanket handler with typed handling: log the exception with `logging.exception`, return a generic detail, and map known errors (auth, timeout, validation) to 4xx/502.

Example fix

// before
except Exception as e:
    raise HTTPException(status_code=500, detail=str(e))

# after
except Exception:
    logging.exception("chat endpoint failed")
    raise HTTPException(status_code=500, detail="Internal server error")
Defensive patterns

Strategy: try-catch

Try / catch

# client side
import requests
try:
    r = requests.post("/api/chat", json=payload, timeout=120)
    if r.status_code >= 500:
        logging.error("server error detail: %s", r.json().get("detail"))
        # detail is str(e) of an unknown inner exception — do not parse it programmatically
    r.raise_for_status()
except requests.Timeout:
    retry_with_backoff()

Prevention

When it happens

Trigger: POST to the chat endpoint when any exception escapes: the LLM provider rejects the API key or times out, `save_session_history` fails to serialize `tool_calls`/response objects, or the response object structure (msg.role/tool_call_id attributes) differs from what the loop expects.

Common situations: Missing/expired LLM API key in .env, rate limits from the model provider, unserializable objects passed to session persistence, or a provider SDK version change that alters message attributes.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/f18cf03b93789cb2. Report an issue: GitHub.