daybook/artifacts/exception_handlers.py
peter d30e2436ab v0.3.0: rename app Daybook -> AgentFeed
Removes the "Daybook" name from everything user- and agent-facing, since no
agents are configured yet and this is the cheap moment to do it.

- UI brand, docs, README, CLAUDE.md -> AgentFeed.
- Ingest env vars DAYBOOK_URL/TOKEN/SOURCE/DATA_DIR/BIND_ADDR/HOST_DATA_DIR/
  KEY_PROVISIONING_API -> AGENTFEED_* (token *values* unchanged).
- Skill: skills/daybook-posting -> skills/agentfeed-posting, daybook_post.py
  -> agentfeed_post.py (+ scripts/ wrapper and its test).
- static/daybook.css -> static/agentfeed.css; localStorage daybook.* ->
  agentfeed.*; templatetag daybook_extras -> agentfeed_extras; multipart
  boundaries; json/csv viewer element ids; daybook_exception_handler ->
  agentfeed_exception_handler; compose service/container -> agentfeed.
- Key-provisioning API now OFF by default (independent of DEBUG); enable with
  AGENTFEED_KEY_PROVISIONING_API=1 on test installs only.
- Posting helper now points at Settings -> API Keys.

Deferred on purpose (a later, separate step): the Django package
`daybook_project`, the `/opt/daybook` install path, and the Forgejo repo name.
The sibling AGENT_DAYBOOK__LLM_TEST name is intentionally untouched.

Full suite: 129 passing; live server verified serving under the new name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 13:10:28 +01:00

24 lines
1,008 B
Python

from rest_framework.response import Response
from rest_framework.views import exception_handler
def agentfeed_exception_handler(exc, context):
"""DRF exception handler that additionally maps pathological-input crashes
to a clean 400 instead of an unhandled 500.
Deeply nested JSON in the request body raises RecursionError inside DRF's
JSONParser (before any view validation runs). RecursionError subclasses
RuntimeError, not ValueError, so DRF's default handler doesn't map it and
it surfaces as a 500. Anything the default handler already knows about is
left to it; anything still unhandled that isn't a RecursionError is
returned as None so Django produces its normal 500.
"""
response = exception_handler(exc, context)
if response is not None:
return response
if isinstance(exc, RecursionError):
return Response(
{"detail": "Request payload is nested too deeply to parse."},
status=400,
)
return None