refactor(server/api): migrate library/media handlers to writeErr(err) (T3b)

This commit is contained in:
2026-05-07 20:48:20 -04:00
parent e382b0d718
commit 91f4f5c18a
7 changed files with 85 additions and 78 deletions
+12 -11
View File
@@ -17,6 +17,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/jackc/pgx/v5"
"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
"git.fabledsword.com/bvandeusen/minstrel/internal/coverart"
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)
@@ -89,23 +90,23 @@ func imageContentType(path string) string {
func (h *handlers) handleGetCover(w http.ResponseWriter, r *http.Request) {
id, ok := parseUUID(chi.URLParam(r, "id"))
if !ok {
writeErr(w, http.StatusBadRequest, "bad_request", "invalid album id")
writeErr(w, apierror.BadRequest("bad_request", "invalid album id"))
return
}
q := dbq.New(h.pool)
album, err := q.GetAlbumByID(r.Context(), id)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
writeErr(w, http.StatusNotFound, "not_found", "album not found")
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "album not found"})
return
}
h.logger.Error("api: get album for cover failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "server error")
writeErr(w, apierror.InternalMsg("server error", err))
return
}
path := resolveAlbumCoverPath(r.Context(), q, album)
if path == "" {
writeErr(w, http.StatusNotFound, "not_found", "cover not found")
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "cover not found"})
return
}
f, err := os.Open(path)
@@ -114,14 +115,14 @@ func (h *handlers) handleGetCover(w http.ResponseWriter, r *http.Request) {
// between stat and open, treat it the same as no-art — the user
// experience (404) matches, and 500 would misleadingly imply a server
// bug rather than a filesystem race.
writeErr(w, http.StatusNotFound, "not_found", "cover not found")
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "cover not found"})
return
}
defer func() { _ = f.Close() }()
info, err := f.Stat()
if err != nil {
h.logger.Error("api: stat cover failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "server error")
writeErr(w, apierror.InternalMsg("server error", err))
return
}
w.Header().Set("Content-Type", imageContentType(path))
@@ -134,32 +135,32 @@ func (h *handlers) handleGetCover(w http.ResponseWriter, r *http.Request) {
func (h *handlers) handleGetStream(w http.ResponseWriter, r *http.Request) {
id, ok := parseUUID(chi.URLParam(r, "id"))
if !ok {
writeErr(w, http.StatusBadRequest, "bad_request", "invalid track id")
writeErr(w, apierror.BadRequest("bad_request", "invalid track id"))
return
}
q := dbq.New(h.pool)
track, err := q.GetTrackByID(r.Context(), id)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
writeErr(w, http.StatusNotFound, "not_found", "track not found")
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "track not found"})
return
}
h.logger.Error("api: get track for stream failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "server error")
writeErr(w, apierror.InternalMsg("server error", err))
return
}
f, err := os.Open(track.FilePath)
if err != nil {
// File vanished (scanner indexed it, filesystem lost it). Treat as
// 404 so clients can fall back to the next item in a queue.
writeErr(w, http.StatusNotFound, "not_found", "track file not found")
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "track file not found"})
return
}
defer func() { _ = f.Close() }()
info, err := f.Stat()
if err != nil {
h.logger.Error("api: stat track failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "server error")
writeErr(w, apierror.InternalMsg("server error", err))
return
}
w.Header().Set("Content-Type", audioContentType(track.FileFormat))