package httperr import ( "fmt" "log" "net/http" "strconv" "time" "git.aiterp.net/lucifer/lucifer/internal/respond" "github.com/google/uuid" ) // Error is an error that can be used. type Error struct { Status int Kind string Message string } func (err Error) Error() string { return err.Kind + ": " + err.Message } // ErrLoginRequired is a common error for when a session is expected, but none is found. var ErrLoginRequired = Error{Status: 401, Kind: "login_required", Message: "You are not logged in."} // ErrAccessDenied is a common error for when a session is expected, but none is found. var ErrAccessDenied = Error{Status: 403, Kind: "access_denied", Message: "You cannot do that."} // NotFound generates a 404 error. func NotFound(model string) Error { return Error{Status: 404, Kind: "not_found", Message: model + " not found"} } // Respond responds with the error using the format in the `respond` package. If // the error is not a httperr.Error, then it'll be logged and a 500 will be returned. func Respond(w http.ResponseWriter, err error) { if httpErr, ok := err.(Error); ok { respond.Error(w, httpErr.Status, httpErr.Kind, httpErr.Message) } else { errIDStr := "" errID, err2 := uuid.NewRandom() if err2 != nil { errID, err2 = uuid.NewUUID() if err2 != nil { errIDStr = strconv.FormatInt(time.Now().UnixNano(), 36) } else { errIDStr = errID.String() } } else { errIDStr = errID.String() } log.Printf("ERROR [%s]: %s", errIDStr, err.Error()) respond.Error(w, 500, "internal_error", fmt.Sprintf("Something went wrong. It has been logged with the ID %s", errIDStr)) } }