Skip to content

Instantly share code, notes, and snippets.

@ribice
Created January 18, 2020 21:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ribice/49c98005a51f8c516cbedb57c0aed176 to your computer and use it in GitHub Desktop.
Save ribice/49c98005a51f8c516cbedb57c0aed176 to your computer and use it in GitHub Desktop.
Handling http errors in Go
package httpresp
import (
"context"
"fmt"
"net/http"
"github.com/go-chi/render"
"github.com/go-pg/pg/v9"
"github.com/ribice/api/pkg/zlog"
)
// Response represents error response
type Response struct {
Status int `json:"-"`
Message string `json:"message,omitempty"`
}
// HTTP error statuses with message
var (
NotFound = &Response{Status: 404}
Unauthorized = &Response{Status: 401, Message: "You are not authorized to access this resource"}
Internal = &Response{Status: 500, Message: "An error occurred. We're already working on it. Please try again later."}
)
// Render is the Renderer for Response struct
func (e *Response) Render(w http.ResponseWriter, r *http.Request) error {
render.Status(r, e.Status)
return nil
}
// Error implements the Error interface
func (e *Response) Error() string {
return e.Message
}
// BadRequest returns http 400 with error message
func BadRequest(msg string) *Response {
return &Response{Status: 400, Message: msg}
}
// BadRequest returns http 400 with error message
func BadRequestF(msg string, args ...interface{}) *Response {
return &Response{Status: 400, Message: fmt.Sprintf(msg, args)}
}
// Respond wraps any error into httperr.Response and returns it for client
func Respond(ctx context.Context, err error) *Response {
// Response writes an error response to client
switch e := err.(type) {
case *Response:
return e
default:
if e == pg.ErrNoRows {
return NotFound
}
zlog.FromContext(ctx).Err(e)
return &Response{Status: 500, Message: e.Error()}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment