package handler import ( "log" "net/http" "strconv" "github.com/go-chi/chi/v5" ) // parseID reads the {id} route parameter. It writes a 400 and reports false when // the value isn't a valid id, so callers can simply return. func parseID(w http.ResponseWriter, r *http.Request) (int64, bool) { id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64) if err != nil { http.Error(w, "Invalid ID", http.StatusBadRequest) return 0, false } return id, true } // sortFromRequest returns the sort order for a listing page. An explicit ?sort= // is remembered in a cookie; without one the last choice is restored, so the // order survives the auto-refresh that reloads these pages. func sortFromRequest(w http.ResponseWriter, r *http.Request, cookie, defaultSort string) string { sortBy := r.URL.Query().Get("sort") if sortBy == "" { return getCookie(r, cookie, defaultSort) } setCookie(w, cookie, sortBy) return sortBy } // serverError logs the underlying failure and shows the user a generic message. // Internal error strings can carry filesystem paths and SQL text, so they are // kept out of the response. func (h *Handler) serverError(w http.ResponseWriter, r *http.Request, context string, err error) { log.Printf("%s %s: %s: %v", r.Method, r.URL.Path, context, err) http.Error(w, "Something went wrong. Please try again.", http.StatusInternalServerError) } // redirectWithError flashes a message and redirects, the standard // Post/Redirect/Get failure path for form submissions. The underlying error is // logged rather than shown. func redirectWithError(w http.ResponseWriter, r *http.Request, path, message string, err error) { if err != nil { log.Printf("%s %s: %s: %v", r.Method, r.URL.Path, message, err) } flashError(w, message) http.Redirect(w, r, path, http.StatusSeeOther) } // redirectWithSuccess flashes a confirmation and redirects. func redirectWithSuccess(w http.ResponseWriter, r *http.Request, path, message string) { flashSuccess(w, message) http.Redirect(w, r, path, http.StatusSeeOther) }