refactor(server): final writeErr migration + ErrNotFound aliases (T3c)
This commit is contained in:
+32
-31
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/auth"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/playlists"
|
||||
@@ -89,7 +90,7 @@ type listPlaylistsResponse struct {
|
||||
func (h *handlers) handleListPlaylists(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -101,7 +102,7 @@ func (h *handlers) handleListPlaylists(w http.ResponseWriter, r *http.Request) {
|
||||
case "user", "system", "all":
|
||||
// valid
|
||||
default:
|
||||
writeErr(w, http.StatusBadRequest, "bad_kind", "kind must be one of: user, system, all")
|
||||
writeErr(w, apierror.BadRequest("bad_kind", "kind must be one of: user, system, all"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,7 +115,7 @@ func (h *handlers) handleListPlaylists(w http.ResponseWriter, r *http.Request) {
|
||||
rows, err := h.playlists.List(r.Context(), caller.ID)
|
||||
if err != nil {
|
||||
h.logger.Error("api: list playlists failed", "err", err)
|
||||
writeErr(w, http.StatusInternalServerError, "server_error", "list failed")
|
||||
writeErr(w, apierror.InternalMsg("list failed", err))
|
||||
return
|
||||
}
|
||||
resp := listPlaylistsResponse{Owned: []playlistRowView{}, Public: []playlistRowView{}}
|
||||
@@ -176,12 +177,12 @@ type createPlaylistBody struct {
|
||||
func (h *handlers) handleCreatePlaylist(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
var body createPlaylistBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid JSON body")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid JSON body"))
|
||||
return
|
||||
}
|
||||
row, err := h.playlists.Create(r.Context(), caller.ID, body.Name, body.Description, body.IsPublic)
|
||||
@@ -198,12 +199,12 @@ func (h *handlers) handleCreatePlaylist(w http.ResponseWriter, r *http.Request)
|
||||
func (h *handlers) handleGetPlaylist(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
detail, err := h.playlists.Get(r.Context(), caller.ID, playlistID)
|
||||
@@ -227,17 +228,17 @@ type updatePlaylistBody struct {
|
||||
func (h *handlers) handleUpdatePlaylist(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
var body updatePlaylistBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid JSON body")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid JSON body"))
|
||||
return
|
||||
}
|
||||
row, err := h.playlists.Update(r.Context(), caller.ID, playlistID, playlists.UpdateInput{
|
||||
@@ -257,12 +258,12 @@ func (h *handlers) handleUpdatePlaylist(w http.ResponseWriter, r *http.Request)
|
||||
func (h *handlers) handleDeletePlaylist(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
if err := h.playlists.Delete(r.Context(), caller.ID, playlistID); err != nil {
|
||||
@@ -282,24 +283,24 @@ type appendTracksBody struct {
|
||||
func (h *handlers) handleAppendTracks(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
var body appendTracksBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid JSON body")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid JSON body"))
|
||||
return
|
||||
}
|
||||
trackIDs := make([]pgtype.UUID, 0, len(body.TrackIDs))
|
||||
for _, s := range body.TrackIDs {
|
||||
u, ok := parseUUID(s)
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", fmt.Sprintf("invalid track id %q", s))
|
||||
writeErr(w, apierror.BadRequest("bad_request", fmt.Sprintf("invalid track id %q", s)))
|
||||
return
|
||||
}
|
||||
trackIDs = append(trackIDs, u)
|
||||
@@ -321,18 +322,18 @@ func (h *handlers) handleAppendTracks(w http.ResponseWriter, r *http.Request) {
|
||||
func (h *handlers) handleRemovePlaylistTrack(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
posStr := chi.URLParam(r, "position")
|
||||
pos64, err := strconv.ParseInt(posStr, 10, 32)
|
||||
if err != nil || pos64 < 0 {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid position")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid position"))
|
||||
return
|
||||
}
|
||||
if err := h.playlists.RemoveTrack(r.Context(), caller.ID, playlistID, int32(pos64)); err != nil {
|
||||
@@ -357,17 +358,17 @@ type reorderTracksBody struct {
|
||||
func (h *handlers) handleReorderPlaylist(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
var body reorderTracksBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid JSON body")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid JSON body"))
|
||||
return
|
||||
}
|
||||
if err := h.playlists.Reorder(r.Context(), caller.ID, playlistID, body.OrderedPositions); err != nil {
|
||||
@@ -389,12 +390,12 @@ func (h *handlers) handleReorderPlaylist(w http.ResponseWriter, r *http.Request)
|
||||
func (h *handlers) handleGetPlaylistCover(w http.ResponseWriter, r *http.Request) {
|
||||
caller, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthenticated", "no session")
|
||||
writeErr(w, apierror.Unauthorized("unauthenticated", "no session"))
|
||||
return
|
||||
}
|
||||
playlistID, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid playlist id")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "invalid playlist id"))
|
||||
return
|
||||
}
|
||||
detail, err := h.playlists.Get(r.Context(), caller.ID, playlistID)
|
||||
@@ -403,7 +404,7 @@ func (h *handlers) handleGetPlaylistCover(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
if detail.CoverPath == nil || *detail.CoverPath == "" {
|
||||
writeErr(w, http.StatusNotFound, "not_found", "no cover")
|
||||
writeErr(w, &apierror.Error{Status: 404, Code: "not_found", Message: "no cover"})
|
||||
return
|
||||
}
|
||||
full := filepath.Join(h.dataDir, *detail.CoverPath)
|
||||
@@ -417,18 +418,18 @@ func (h *handlers) handleGetPlaylistCover(w http.ResponseWriter, r *http.Request
|
||||
func (h *handlers) writePlaylistErr(w http.ResponseWriter, err error, op string) {
|
||||
switch {
|
||||
case errors.Is(err, playlists.ErrNotFound):
|
||||
writeErr(w, http.StatusNotFound, "not_found", "playlist not found")
|
||||
writeErr(w, apierror.NotFound("playlist"))
|
||||
case errors.Is(err, playlists.ErrForbidden):
|
||||
writeErr(w, http.StatusForbidden, "not_authorized", "you don't own this playlist")
|
||||
writeErr(w, apierror.Forbidden("not_authorized", "you don't own this playlist"))
|
||||
case errors.Is(err, playlists.ErrSystemPlaylistReadonly):
|
||||
writeErr(w, http.StatusForbidden, "system_playlist_readonly", "system-generated playlists cannot be edited")
|
||||
writeErr(w, apierror.Forbidden("system_playlist_readonly", "system-generated playlists cannot be edited"))
|
||||
case errors.Is(err, playlists.ErrInvalidInput):
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", err.Error())
|
||||
writeErr(w, apierror.BadRequest("bad_request", err.Error()))
|
||||
case errors.Is(err, playlists.ErrTrackNotFound):
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "one of the supplied track ids does not exist")
|
||||
writeErr(w, apierror.BadRequest("bad_request", "one of the supplied track ids does not exist"))
|
||||
default:
|
||||
h.logger.Error("api: playlist op failed", "op", op, "err", err)
|
||||
writeErr(w, http.StatusInternalServerError, "server_error", op+" failed")
|
||||
writeErr(w, apierror.InternalMsg(op+" failed", err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user