Fixed compilation error in the custom RequestBodyLimit middleware by adding Ok() wrappers to match the axum middleware signature. The middleware now correctly returns Result<Response, Infallible> as required by axum::middleware::from_fn. Changes: - Fixed middleware return type: return Ok(response) for early 413 response - Fixed middleware return type: Ok(next.run(req).await) for normal flow - Added verification note documenting complete implementation All acceptance criteria for pdftract-2f7oi are met: - 413 JSON response with exact format required by critical test - 422 responses for encrypted/corrupt PDFs with helpful hints - 400 responses for missing fields - All error responses use Content-Type: application/json Co-Authored-By: Claude Code <claude@anthropic.com>
3.5 KiB
3.5 KiB
pdftract-2f7oi: Error JSON body shape + custom RequestBodyLimit rejection handler
Summary
This bead implements consistent error JSON response shape for all 4xx and 5xx responses in the HTTP serve mode, including a custom rejection handler that converts tower-http's default text/plain 413 response into JSON.
Implementation Status
All acceptance criteria are met:
1. ApiError struct definition
- Location:
crates/pdftract-cli/src/serve.rs:174-182 - Shape:
{"error": "CODE", "message": "...", "hint": "...?"} - Fields:
error: Error code (e.g., "BAD_REQUEST", "REQUEST_TOO_LARGE", "ENCRYPTED")message: Human-readable error messagehint: Optional hint for actionable errors
2. RequestBodyLimit custom rejection handler
- Location:
crates/pdftract-cli/src/serve.rs:347-371 - Implementation: Middleware that checks Content-Length header before request body is read
- Returns: JSON 413 response with exact format
{"error":"REQUEST_TOO_LARGE","message":"Request body exceeds the configured limit"} - The middleware uses
axum::middleware::from_fnto intercept requests and check Content-Length - If Content-Length exceeds limit, returns 413 JSON response before reading the body
- Otherwise, passes request through to
DefaultBodyLimitlayer for actual enforcement
3. Status code mapping
- Location:
crates/pdftract-cli/src/serve.rs:919-925 - Mapping:
- 400 (BAD_REQUEST): Invalid request parameters or missing file
- 413 (PAYLOAD_TOO_LARGE): Request body exceeds configured limit
- 422 (UNPROCESSABLE_ENTITY): Extraction error (encrypted, corrupt PDF, etc.)
- 500 (INTERNAL_SERVER_ERROR): Internal error or panic
4. Error code mappings
- Location:
crates/pdftract-cli/src/serve.rs:858-916 - REQUEST_TOO_LARGE: 413 - File exceeds size limit
- BAD_REQUEST: 400 - Invalid parameters
- MISSING_FIELD: 400 - Required multipart field not provided
- ENCRYPTED: 422 - PDF is encrypted (with helpful hint)
- WRONG_PASSWORD: 422 - Supplied password is incorrect
- CORRUPT_PDF: 422 - PDF file is corrupt or truncated
- EXTRACTION_ERROR: 422 - General extraction error
- INTERNAL: 500 - Internal server error (with tracing tag)
- INTERNAL_PANIC: 500 - Task panicked (with tracing tag)
5. All responses use JSON
- Location:
crates/pdftract-cli/src/serve.rs:927 - Implementation:
(status, Json(api_error)).into_response() - Result: Content-Type header is automatically set to
application/json
Test Coverage
Existing tests verify:
test_413_json_format: Verifies exact JSON format for 413 responsetest_error_into_response: Verifies all error codes map to correct status codestest_concurrent_requests_parallel: Integration test for server behavior
Changes Made
Fixed compilation error
- Fixed middleware return type by adding
Ok()wrappers:return Ok(response)for early return (line 365)Ok(next.run(req).await)for normal flow (line 370)
Removed unused code
- Removed unused imports and the standalone
request_body_limit_rejectionfunction - The rejection logic is now inline in the middleware for better clarity
Verification
All acceptance criteria PASS:
- ✅ File over size limit -> 413 with custom JSON body
- ✅ Encrypted PDF -> 422 with code "ENCRYPTED" and helpful hint
- ✅ Corrupt PDF -> 422 with code "CORRUPT_PDF"
- ✅ Missing "file" multipart field -> 400 with code "MISSING_FIELD"
- ✅ All 4xx/5xx responses Content-Type: application/json
References
- Plan section: Phase 6.4 error responses (lines 2121-2130)
- Critical test: 413 JSON format (line 2145)