Every error response in the { error, code, details? } format (step 2)
Moves every remaining hand-built error response onto ApiError: ~300
sites across faces, image, video, files, memories, versions,
duplicates, favorites, libraries, auth, clip/unified search, prefs,
reels, tts, insight chat, persona chat, knowledge and personas.
- 500s: the body was the error's text (anyhow / diesel / {:?}); now
ApiError::internal logs it and sends a generic message.
- Each 4xx/502/503 has a stable code and a message written for users;
statuses are unchanged. Shared helpers per module (faces_unavailable,
person_not_found, unknown_library, insight_not_found, ...).
- Pre-format top-level fields kept where clients read them: upload 409
duplicate_of / content_hash / library_name.
- PersonaChatError converts into ApiError in one place.
- Multipart upload errors use the format (error::multipart_config).
- Guard test: no non-test code builds HttpResponse::<error>() by hand.
Closes #202
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1836f1b9ca
commit
431c3a7492
23 files changed
+894
-542
No files matched your search
@@ -797,6 +797,15 @@ GET /timezones (IANA zone list from chrono-tz; unauthentic
|
||||
**Service Builder Pattern:**
|
||||
Routes are registered via composable `ServiceBuilder` trait in `service.rs`. Allows modular feature addition.
|
||||
|
||||
**Error responses (`src/error.rs`, #202):**
|
||||
Every error body is `{"error": "<message safe to show a user>", "code": "<stable_snake_case>", "details"?: {...}}`.
|
||||
Build them with `ApiError` (`bad_request` / `not_found` / `conflict` / `unavailable` / `bad_gateway` / ... `(code, message)`),
|
||||
returned as `Err(..)` from an `ApiResult` handler or via `.into_response()`. Unexpected failures go through
|
||||
`ApiError::internal(cause)` (or `?` on anyhow / diesel): a 500 `internal` whose cause is logged, never sent, since it can
|
||||
hold SQL and library paths. Never rename a code a client may branch on; add a new one. Don't put file paths in `details`.
|
||||
Request-parsing failures, the auth extractor, multipart uploads and unknown routes use the format too (configs in
|
||||
`error.rs`, registered in `main.rs`). A test fails if a handler builds `HttpResponse::NotFound()` etc. by hand.
|
||||
|
||||
**Path Validation:**
|
||||
Always use `is_valid_full_path(&base_path, &requested_path, check_exists)` to prevent directory traversal attacks.
|
||||
|
||||
|
||||
Reference in new issue
Block a user