#015 — deeply nested JSON raised RecursionError (a RuntimeError, not ValueError) and became an unhandled 500 on two paths: - json-kind content validation now catches RecursionError -> 400. - Added a custom DRF EXCEPTION_HANDLER (artifacts/exception_handlers.py, wired via REST_FRAMEWORK) mapping otherwise-unhandled RecursionError -> 400, covering the parser-level crash on deeply nested request bodies (metadata etc.) too. #016 — wrap_csv_viewer handed Grid.js rows without reconciling width to the header, so over-long rows silently dropped cells. Now normalizes every row to the max width: long rows widen the columns (auto-named "Column N"), short rows pad with "". No cell is dropped. Both verified live; 4 regression tests added. 106 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
24 lines
1,006 B
Python
24 lines
1,006 B
Python
from rest_framework.response import Response
|
|
from rest_framework.views import exception_handler
|
|
|
|
|
|
def daybook_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
|