package slerrors import ( "github.com/gin-gonic/gin" "github.com/gisle/stufflog/internal/generate" "log" "net/http" "strconv" ) type SLError struct { Code int `json:"code"` Text string `json:"text"` } func (err *SLError) Error() string { return "slerror: " + err.Text + " (Suggested status code: " + strconv.Itoa(err.Code) + ")" } func (err *SLError) WithText(text string) *SLError { return &SLError{Code: err.Code, Text: text} } // GinRespond responds to a gin request. func GinRespond(c *gin.Context, err error) { serr := Wrap(err) type errResponse struct { Error *SLError `json:"error"` } if serr.Code == 500 { errId := generate.ID("E", 16) log.Println("Internal Server Error", errId, "--", err.Error()) c.JSON(500, errResponse{&SLError{ Code: 500, Text: "Internal server error: ref " + errId, }}) return } c.JSON(serr.Code, errResponse{serr}) } // Wrap wraps an error func Wrap(err error) *SLError { if slerr, ok := err.(*SLError); ok { return slerr } if _, ok := err.(*strconv.NumError); ok { return &SLError{Code: http.StatusBadRequest, Text: err.Error()} } return &SLError{Code: http.StatusInternalServerError, Text: err.Error()} } func NotFound(noun string) *SLError { return &SLError{Code: http.StatusNotFound, Text: noun + " not found"} } func PreconditionFailed(message string) *SLError { return &SLError{Code: http.StatusPreconditionFailed, Text: message} } func LoginFailed() *SLError { return &SLError{Code: http.StatusForbidden, Text: "Login Failed"} } func Unauthorized() *SLError { return &SLError{Code: http.StatusUnauthorized, Text: "Unauthorized"} } func IsNotFound(err error) bool { if serr, ok := err.(*SLError); ok && serr.Code == 404 { return true } return false }