You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
1.6 KiB
58 lines
1.6 KiB
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))
|
|
}
|
|
}
|