datawhalechina/hello-agents · error · HTTPException

处理失败: {str(e)}

Error message

处理失败: {str(e)}

What it means

A generic 500 from the /writing/coach endpoint in api/routes/writing.py wrapping any non-HTTPException error raised while running the writing task. In practice the raising code is the LLM call (network failure, timeout, quota, malformed response), since the rest of the handler only formats strings. The handler correctly re-raises HTTPException untouched (line 'except HTTPException: raise'), so this 500 always originates from the underlying AI client or response parsing.

Source

Thrown at Co-creation-projects/Apricity-InnocoreAI/api/routes/writing.py:138

        prompt = prompts.get(request.task, prompts["polish"])
        
        # 调用 LLM 处理
        response = await llm.ainvoke(prompt)
        result_content = response.content if hasattr(response, 'content') else str(response)
        
        return {
            "success": True,
            "task": request.task,
            "style": request.style,
            "original": request.text,
            "result": result_content
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"写作助手处理失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"处理失败: {str(e)}")

@router.post("/explain", response_model=Dict[str, Any])
async def explain_concept(request: ExplainRequest):
    """解释复杂概念"""
    try:
        # 模拟概念解释
        return {
            "success": True,
            "concept": request.concept,
            "explanation": f"[Detailed explanation of {request.concept} in accessible terms while maintaining technical accuracy]",
            "examples": ["Example 1", "Example 2"],
            "timestamp": "2024-01-15T10:30:00Z"
        }
        
    except Exception as e:
        logger.error(f"概念解释失败: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

View on GitHub (pinned to 606a07d341)

Solutions

  1. Check server logs for the logged line '写作助手处理失败: ...' — str(e) names the real cause (auth, timeout, rate limit)
  2. Retry once after a short delay for transient network/429 errors, or add exponential backoff around the LLM call
  3. Validate request.task against the supported set ('polish', etc.) before building prompts, returning 422 for unknown tasks
  4. Guard result_content extraction: use response.choices[0].message.content or the SDK's typed accessor, defaulting to a clear message when content is empty
  5. Do not echo str(e) to clients — return a generic message and keep details in logs

Example fix

# before
except Exception as e:
    logger.error(f"写作助手处理失败: {str(e)}")
    raise HTTPException(status_code=500, detail=f"处理失败: {str(e)}")

# after
from openai import APIConnectionError, RateLimitError, AuthenticationError
except (RateLimitError, APIConnectionError):
    raise HTTPException(status_code=503, detail="AI service temporarily unavailable, retry later")
except AuthenticationError:
    raise HTTPException(status_code=502, detail="AI credentials rejected")
except Exception:
    logger.exception("写作助手处理失败")
    raise HTTPException(status_code=500, detail="处理失败")
Defensive patterns

Strategy: retry

Validate before calling

valid_tasks = {'polish', 'rewrite', 'expand'}
if request.task not in valid_tasks:
    return HTTP 422 before calling the endpoint

Try / catch

for attempt in range(3):
    try:
        return client.post('/writing/coach', json=payload)
    except HTTPError as e:
        if e.response.status_code == 500 and attempt < 2:
            time.sleep(2 ** attempt); continue
        raise

Prevention

When it happens

Trigger: POST /writing/coach where llm.ainvoke/completion raises: expired or invalid API key (401), rate limit (429), network timeout to the OpenAI-compatible endpoint, or response.content being None/empty so result_content extraction raises AttributeError/KeyError. An unknown request.task falling through a prompt dict lookup could also KeyError before the guard.

Common situations: Expired API key mid-deployment; shared key hitting rate limits under load; self-hosted LLM gateway temporarily down; model name in config not available on the endpoint; response shape differs from expected (e.g. reasoning models returning empty content) causing the extraction code to raise.

Related errors


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