mirror of
https://github.com/m1k1o/neko.git
synced 2025-08-02 16:29:55 +02:00
refactor HTTP error.
This commit is contained in:
parent
d46c5d9d30
commit
4fa11e6a2a
15 changed files with 166 additions and 102 deletions
|
@ -9,16 +9,12 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type ErrResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func HttpJsonRequest(w http.ResponseWriter, r *http.Request, res interface{}) bool {
|
||||
if err := json.NewDecoder(r.Body).Decode(res); err != nil {
|
||||
if err == io.EOF {
|
||||
HttpBadRequest(w, "no data provided")
|
||||
HttpBadRequest(w).WithInternalErr(err).Msg("no data provided")
|
||||
} else {
|
||||
HttpBadRequest(w, err)
|
||||
HttpBadRequest(w).WithInternalErr(err).Msg("unable to parse provided data")
|
||||
}
|
||||
|
||||
return false
|
||||
|
@ -27,21 +23,15 @@ func HttpJsonRequest(w http.ResponseWriter, r *http.Request, res interface{}) bo
|
|||
return true
|
||||
}
|
||||
|
||||
func HttpJsonResponse(w http.ResponseWriter, status int, res interface{}) {
|
||||
func HttpJsonResponse(w http.ResponseWriter, code int, res interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
w.WriteHeader(code)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(res); err != nil {
|
||||
log.Err(err).Str("module", "http").Msg("sending http json response failed")
|
||||
}
|
||||
}
|
||||
|
||||
func HttpError(w http.ResponseWriter, status int, res interface{}) {
|
||||
HttpJsonResponse(w, status, &ErrResponse{
|
||||
Message: fmt.Sprint(res),
|
||||
})
|
||||
}
|
||||
|
||||
func HttpSuccess(w http.ResponseWriter, res ...interface{}) {
|
||||
if len(res) == 0 {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
@ -50,34 +40,108 @@ func HttpSuccess(w http.ResponseWriter, res ...interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
func HttpBadRequest(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusBadRequest, "bad request", res...)
|
||||
// HTTPError is an error with a message and an HTTP status code.
|
||||
type HTTPError struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
|
||||
InternalErr error `json:"-"`
|
||||
InternalMsg string `json:"-"`
|
||||
|
||||
w http.ResponseWriter `json:"-"`
|
||||
}
|
||||
|
||||
func HttpUnauthorized(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusUnauthorized, "invalid or missing access token", res...)
|
||||
func (e *HTTPError) Error() string {
|
||||
if e.InternalMsg != "" {
|
||||
return e.InternalMsg
|
||||
}
|
||||
return fmt.Sprintf("%d: %s", e.Code, e.Message)
|
||||
}
|
||||
|
||||
func HttpForbidden(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusForbidden, "access token does not have the required scope", res...)
|
||||
func (e *HTTPError) Cause() error {
|
||||
if e.InternalErr != nil {
|
||||
return e.InternalErr
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func HttpNotFound(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusNotFound, "resource not found", res...)
|
||||
// WithInternalErr adds internal error information to the error
|
||||
func (e *HTTPError) WithInternalErr(err error) *HTTPError {
|
||||
e.InternalErr = err
|
||||
return e
|
||||
}
|
||||
|
||||
func HttpUnprocessableEntity(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusUnprocessableEntity, "unprocessable entity", res...)
|
||||
// WithInternalMsg adds internal message information to the error
|
||||
func (e *HTTPError) WithInternalMsg(msg string) *HTTPError {
|
||||
e.InternalMsg = msg
|
||||
return e
|
||||
}
|
||||
|
||||
func HttpInternalServerError(w http.ResponseWriter, res ...interface{}) {
|
||||
defHttpError(w, http.StatusInternalServerError, "internal server error", res...)
|
||||
// WithInternalMsg adds internal formated message information to the error
|
||||
func (e *HTTPError) WithInternalMsgf(fmtStr string, args ...interface{}) *HTTPError {
|
||||
e.InternalMsg = fmt.Sprintf(fmtStr, args...)
|
||||
return e
|
||||
}
|
||||
|
||||
func defHttpError(w http.ResponseWriter, status int, text string, res ...interface{}) {
|
||||
if len(res) == 0 {
|
||||
HttpError(w, status, text)
|
||||
} else {
|
||||
HttpError(w, status, res[0])
|
||||
// Sends error with custom formated message
|
||||
func (e *HTTPError) Msgf(fmtSt string, args ...interface{}) {
|
||||
e.Message = fmt.Sprintf(fmtSt, args...)
|
||||
e.Send()
|
||||
}
|
||||
|
||||
// Sends error with custom message
|
||||
func (e *HTTPError) Msg(str string) {
|
||||
e.Message = str
|
||||
e.Send()
|
||||
}
|
||||
|
||||
// Sends error with default status text
|
||||
func (e *HTTPError) Send() {
|
||||
if e.Message == "" {
|
||||
e.Message = http.StatusText(e.Code)
|
||||
}
|
||||
|
||||
logger := log.Error().
|
||||
Err(e.InternalErr).
|
||||
Str("module", "http").
|
||||
Int("code", e.Code)
|
||||
|
||||
message := e.Message
|
||||
if e.InternalMsg != "" {
|
||||
message = e.InternalMsg
|
||||
}
|
||||
|
||||
logger.Msg(message)
|
||||
HttpJsonResponse(e.w, e.Code, e)
|
||||
}
|
||||
|
||||
func HttpError(w http.ResponseWriter, code int) *HTTPError {
|
||||
return &HTTPError{
|
||||
Code: code,
|
||||
w: w,
|
||||
}
|
||||
}
|
||||
|
||||
func HttpBadRequest(w http.ResponseWriter) *HTTPError {
|
||||
return HttpError(w, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func HttpUnauthorized(w http.ResponseWriter) *HTTPError {
|
||||
return HttpError(w, http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
func HttpForbidden(w http.ResponseWriter) *HTTPError {
|
||||
return HttpError(w, http.StatusForbidden)
|
||||
}
|
||||
|
||||
func HttpNotFound(w http.ResponseWriter) *HTTPError {
|
||||
return HttpError(w, http.StatusNotFound)
|
||||
}
|
||||
|
||||
func HttpUnprocessableEntity(w http.ResponseWriter) *HTTPError {
|
||||
return HttpError(w, http.StatusUnprocessableEntity)
|
||||
}
|
||||
|
||||
func HttpInternalServerError(w http.ResponseWriter, err error) *HTTPError {
|
||||
return HttpError(w, http.StatusInternalServerError).WithInternalErr(err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue