#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>
This commit is contained in:
parent
5c53643349
commit
5f872b4b32
6 changed files with 110 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# 015 — Deeply nested JSON raises `RecursionError` → unhandled HTTP 500 (two code paths)
|
||||
|
||||
**Status:** Open
|
||||
**Status:** Fixed
|
||||
**Severity:** Medium — unhandled 500 where a 400 is correct; small (~30 KB)
|
||||
request crashes the handling worker (minor DoS shape); full traceback
|
||||
exposed when `DEBUG=True`.
|
||||
|
|
@ -91,4 +91,21 @@ this.
|
|||
|
||||
## Resolution
|
||||
|
||||
_(pending)_
|
||||
Both paths fixed:
|
||||
|
||||
- **Path 1** (`json`-kind content validation): `validate_content_shape` now
|
||||
catches `RecursionError` alongside `(TypeError, ValueError)`, returning
|
||||
the same `400 content must be valid JSON: …`.
|
||||
- **Path 2** (deep nesting anywhere in the request body, crashing DRF's
|
||||
parser before the view): added a custom DRF `EXCEPTION_HANDLER`
|
||||
(`artifacts/exception_handlers.py`, wired via `REST_FRAMEWORK` in
|
||||
settings) that maps otherwise-unhandled `RecursionError` to
|
||||
`400 Request payload is nested too deeply to parse.` This also covers the
|
||||
same class of error in `metadata`/`tag_colors` string parsing. Anything
|
||||
that isn't a RecursionError still falls through to Django's normal 500.
|
||||
|
||||
Verified live: deep `json` content and a ~5000-deep `metadata` body both
|
||||
return 400; shallow payloads still 201. Tests added in
|
||||
`tests/api/test_artifacts.py`. (A depth-cap parser was considered but the
|
||||
exception-handler approach is simpler and covers every recursive-descent
|
||||
site at once; prod `DEBUG=False` already suppresses the traceback page.)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 016 — Ragged CSV rows silently lose data in the rendered table (server doesn't normalize row width)
|
||||
|
||||
**Status:** Open
|
||||
**Status:** Fixed
|
||||
**Severity:** Low-Medium — silent data loss in the primary rendered view;
|
||||
raw sidecar is unaffected, so it's a fidelity/display bug, not permanent
|
||||
loss.
|
||||
|
|
@ -82,4 +82,13 @@ raw sidecar.
|
|||
|
||||
## Resolution
|
||||
|
||||
_(pending)_
|
||||
Implemented option (b) in `wrap_csv_viewer`: normalize every row to the
|
||||
maximum row width before handing data to Grid.js. Rows longer than the
|
||||
header widen the column set (extra columns auto-named `Column N`); rows
|
||||
shorter than the width are padded with empty strings. No cell is ever
|
||||
dropped, matching "server owns normalization, never silently lose content."
|
||||
|
||||
Verified live with the issue's exact input (`a,b,c` / `1,2,3,4,5` / `6,7`):
|
||||
grid data becomes `columns=[a,b,c,Column 4,Column 5]`,
|
||||
`data=[[1,2,3,4,5],[6,7,"","",""]]` — the previously-dropped `4` and `5`
|
||||
now render. Test added in `tests/api/test_artifacts.py`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue