package htp
import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
)
func W500(w http.ResponseWriter, log *slog.Logger, err error, id string, msg string) {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Error %q: %s", id, msg)))
log.Error("", "err", err, "err_id", id, "code", http.StatusInternalServerError)
}
func W400(w http.ResponseWriter, log *slog.Logger, err error, id string, msg string) {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Error %q: %s", id, msg)))
log.Info("", "err", err, "err_id", id, "code", http.StatusBadRequest)
}
func Json(w http.ResponseWriter, log *slog.Logger, errId string, body any) {
bytes, err := json.Marshal(body)
if err != nil {
W500(w, log, err, errId, BugMarshal)
return
}
w.Write(bytes)
}
func Read(w http.ResponseWriter, r *http.Request, log *slog.Logger, errId string, body any) bool {
defer r.Body.Close()
bytes, err := io.ReadAll(r.Body)
if err != nil {
W400(w, log, err, errId, BadBody)
return false
}
err = json.Unmarshal(bytes, body)
if err != nil {
W400(w, log, err, errId+"-json-unmarshal", BadBody)
return false
}
return true
}
// WriteRedirect
// Typically used if a resource created but for some reason we failed to get all the details
// to send to the user.
func WRdr(w http.ResponseWriter, r *http.Request, log *slog.Logger, err error, id string, to string) {
log.Error("", "err", err, "err_id", id, "code", http.StatusSeeOther, "to", to)
http.Redirect(w, r, to, http.StatusSeeOther)
}
// explaining bugs to users
const (
BugLogin = "Server bug not finding login info where it is expected to be"
BugScan = "Server bug fetching database record"
BugMarshal = "Server bug encoding valid resource"
BugAdminSignup = "Server bug where server admin should have been created but was not"
BugTemplate = "Server bug trying to find nonexistent template"
)
// explaining issue conditions that are not necessarily a bug (e.g. db is down/corrupted, disk is full/read only) to users
const (
IssRecDel = "Could not delete recipe. Try again later."
IssRecAdd = "Could not add recipe. Try again later."
IssRecInvalid = "Could not parse recipe form."
IssRecAddOk = "Recipe added but could not find its id. Search for the new recipe on the listings page."
IssRecEditFind = "Could not find recipe to edit"
IssRecEdit = "Error updating recipe"
IssRecDetailFind = "Error updating recipe"
IssRecSearch = "Error fetching recipes"
IssRecCount = "Error counting recipes"
IssLtrAdd = "Error adding recipe to list of recipes to try later"
IssLtrDel = "Error removing recipe from list of recipes to try later"
IssId = "Invalid id"
IssUsrCreate = "Failed to create user"
IssUsrNoUser = "Must pass username to create user"
IssUsrNoPass = "Must pass password to create user"
IssUsrLoginFind = "Could not log in: failed querying for user"
IssUsrLoginSession = "Login info is valid, but could not create login session"
IssUsrWhoami = "Issue fetching own user info"
IssUsrLogoutSessionFind = "Issue finding session to delete"
IssUsrSessionDel = "Issue deleting user session"
IssRolAdd = "Failed to add user role"
)
// explaining things the user did wrong
const (
BadBody = "Data or format of request was bad"
BadGroup = "You are not a part of that group"
BadPage = "Page must be >= 0"
BadRecPageSize = "Page size must be between 1 & 200"
BadRecSearchType = "Bad search type"
BadRolAdd = "add role: userId or role not provided"
)
// Contextual information to developer on why issue would have occurred
const WhyNoContext = "no context auth when it is expected"