104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/render"
|
|
)
|
|
|
|
// ErrResponse renderer type for handling all sorts of errors.
|
|
//
|
|
// In the best case scenario, the excellent github.com/pkg/errors package
|
|
// helps reveal information on the error, setting it on Err, and in the Render()
|
|
// method, using it to set the application-specific error code in AppCode.
|
|
type ErrResponse struct {
|
|
Err error `json:"-"` // low-level runtime error
|
|
HTTPStatusCode int `json:"-"` // http response status code
|
|
|
|
StatusText string `json:"status"` // user-level status message
|
|
AppCode int64 `json:"code,omitempty"` // application-specific error code
|
|
ErrorText string `json:"error,omitempty"` // application-level error message, for debugging
|
|
}
|
|
|
|
func (e *ErrResponse) Render(_ http.ResponseWriter, r *http.Request) error {
|
|
render.Status(r, e.HTTPStatusCode)
|
|
|
|
return nil
|
|
}
|
|
|
|
func ErrBasic(status int) *ErrResponse {
|
|
return &ErrResponse{
|
|
HTTPStatusCode: status,
|
|
StatusText: http.StatusText(status),
|
|
}
|
|
}
|
|
|
|
func ErrGeneric(err error, status int) *ErrResponse {
|
|
resp := ErrBasic(status)
|
|
resp.Err = err
|
|
resp.ErrorText = err.Error()
|
|
|
|
return resp
|
|
}
|
|
|
|
func ErrBadRequest(err error) *ErrResponse {
|
|
return ErrGeneric(err, http.StatusBadRequest)
|
|
}
|
|
|
|
func ErrNotFound() *ErrResponse {
|
|
return ErrBasic(http.StatusNotFound)
|
|
}
|
|
|
|
func ErrUnauthorized() *ErrResponse {
|
|
return ErrBasic(http.StatusUnauthorized)
|
|
}
|
|
|
|
func ErrForbidden() *ErrResponse {
|
|
return ErrBasic(http.StatusForbidden)
|
|
}
|
|
|
|
func ErrRendering(err error) *ErrResponse {
|
|
return &ErrResponse{
|
|
Err: err,
|
|
HTTPStatusCode: http.StatusUnprocessableEntity,
|
|
StatusText: "Error rendering response.",
|
|
ErrorText: err.Error(),
|
|
}
|
|
}
|
|
|
|
func RenderRender(w http.ResponseWriter, r *http.Request, resp render.Renderer) {
|
|
// Try to render the response
|
|
if err := render.Render(w, r, resp); err != nil {
|
|
// If error, try to render that an error occurred
|
|
if err := render.Render(w, r, ErrRendering(err)); err != nil {
|
|
// If error, panic
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func RenderBadRequest(w http.ResponseWriter, r *http.Request, err error) {
|
|
RenderRender(w, r, ErrBadRequest(err))
|
|
}
|
|
|
|
func RenderServerError(_ http.ResponseWriter, _ *http.Request, err error) {
|
|
// Panic so the stack trace is printed
|
|
panic(err)
|
|
}
|
|
|
|
func RenderNotFound(w http.ResponseWriter, r *http.Request) {
|
|
RenderRender(w, r, ErrNotFound())
|
|
}
|
|
|
|
func RenderUnauthorized(w http.ResponseWriter, r *http.Request) {
|
|
RenderRender(w, r, ErrUnauthorized())
|
|
}
|
|
|
|
func RenderForbidden(w http.ResponseWriter, r *http.Request) {
|
|
RenderRender(w, r, ErrForbidden())
|
|
}
|
|
|
|
func RenderRendering(w http.ResponseWriter, r *http.Request, err error) {
|
|
RenderRender(w, r, ErrRendering(err))
|
|
}
|