diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-19 00:25:06 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-19 00:25:06 +0300 |
| commit | 13e97b48d4de2ed7007a9530ed3a4b42b631ce35 (patch) | |
| tree | 047ff0b14be3269b0ec2e33c31d4920712ecf63d /player-server/internal/api/handlers.go | |
| parent | 084848864d78012d801fba85b5827206d5eccac5 (diff) | |
Map service errors to correct HTTP status codes (was 500)
Three more handlers had the same pattern as the RevokeShare bug fixed
in 0848488: the service returned a plain errors.New(...) for an
expected condition, so handleError fell through to its default 500
branch instead of mapping to 404/400.
- browse.GetThumbnail → ErrNotFound (404 instead of 500) when the
media row has no thumbnail path.
- tag.RemoveTag → ErrNotFound (404 instead of 500) when the tag name
does not exist. DELETE /media/{id}/tags/{unknown} now returns 404.
- write.RegenerateSetCover → new sentinel ErrEmptySetForCover, mapped
to 400 in handleError, when the target set contains no media files
eligible to be promoted to a cover.
S15 (auth-boundary negatives) is tightened: the share-revoke step used
to accept {404, 500} as a workaround for the bug; it now requires 404.
A new section C2 locks in the three regressions above so they cannot
silently return 500 again.
Verified end-to-end via curl: DELETE /media/{id}/tags/unknown → 404,
DELETE /shares/unknown-token → 404. Full LLM e2e suite 15/15 still
passes against the rebuilt server.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'player-server/internal/api/handlers.go')
| -rw-r--r-- | player-server/internal/api/handlers.go | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/player-server/internal/api/handlers.go b/player-server/internal/api/handlers.go index b276b10..1423a84 100644 --- a/player-server/internal/api/handlers.go +++ b/player-server/internal/api/handlers.go @@ -57,7 +57,8 @@ func handleError(w http.ResponseWriter, err error) { writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid credentials"}) case errors.Is(err, service.ErrUnsupportedExtension), errors.Is(err, service.ErrInvalidFeed), - errors.Is(err, service.ErrCannotDeleteSelf): + errors.Is(err, service.ErrCannotDeleteSelf), + errors.Is(err, service.ErrEmptySetForCover): badRequest(w, err.Error()) default: writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) |
