Improve the UX for users of the errors package.

By making the error helper functions variadic functions, you can pass either a string (like the existing behaviour) or a format and verbs that will then be formatted for you.

This doesn’t break any existing API’s, but it prevents people using this package to have to call `fmt.Sprintf` whenever they would like to format the error detail.
This commit is contained in:
Sander van Harmelen 2017-05-31 15:29:03 +02:00
parent a7312f5c7e
commit 4bc44d79c6

View File

@ -1,14 +1,14 @@
// Package errors is an interface for defining detailed errors // Package errors provides a way to return detailed information
// for an RPC request error. The error is normally JSON encoded.
package errors package errors
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
) )
// Errors provide a way to return detailed information // Error implements the error interface.
// for an RPC request error. The error is normally
// JSON encoded.
type Error struct { type Error struct {
Id string `json:"id"` Id string `json:"id"`
Code int32 `json:"code"` Code int32 `json:"code"`
@ -21,6 +21,7 @@ func (e *Error) Error() string {
return string(b) return string(b)
} }
// New generates a custom error.
func New(id, detail string, code int32) error { func New(id, detail string, code int32) error {
return &Error{ return &Error{
Id: id, Id: id,
@ -30,6 +31,8 @@ func New(id, detail string, code int32) error {
} }
} }
// Parse tries to parse a JSON string into an error. If that
// fails, it will set the given string as the error detail.
func Parse(err string) *Error { func Parse(err string) *Error {
e := new(Error) e := new(Error)
errr := json.Unmarshal([]byte(err), e) errr := json.Unmarshal([]byte(err), e)
@ -39,47 +42,52 @@ func Parse(err string) *Error {
return e return e
} }
func BadRequest(id, detail string) error { // BadRequest generates a 400 error.
func BadRequest(id, format string, a ...interface{}) error {
return &Error{ return &Error{
Id: id, Id: id,
Code: 400, Code: 400,
Detail: detail, Detail: fmt.Sprintf(format, a...),
Status: http.StatusText(400), Status: http.StatusText(400),
} }
} }
func Unauthorized(id, detail string) error { // Unauthorized generates a 401 error.
func Unauthorized(id, format string, a ...interface{}) error {
return &Error{ return &Error{
Id: id, Id: id,
Code: 401, Code: 401,
Detail: detail, Detail: fmt.Sprintf(format, a...),
Status: http.StatusText(401), Status: http.StatusText(401),
} }
} }
func Forbidden(id, detail string) error { // Forbidden generates a 403 error.
func Forbidden(id, format string, a ...interface{}) error {
return &Error{ return &Error{
Id: id, Id: id,
Code: 403, Code: 403,
Detail: detail, Detail: fmt.Sprintf(format, a...),
Status: http.StatusText(403), Status: http.StatusText(403),
} }
} }
func NotFound(id, detail string) error { // NotFound generates a 404 error.
func NotFound(id, format string, a ...interface{}) error {
return &Error{ return &Error{
Id: id, Id: id,
Code: 404, Code: 404,
Detail: detail, Detail: fmt.Sprintf(format, a...),
Status: http.StatusText(404), Status: http.StatusText(404),
} }
} }
func InternalServerError(id, detail string) error { // InternalServerError generates a 500 error.
func InternalServerError(id, format string, a ...interface{}) error {
return &Error{ return &Error{
Id: id, Id: id,
Code: 500, Code: 500,
Detail: detail, Detail: fmt.Sprintf(format, a...),
Status: http.StatusText(500), Status: http.StatusText(500),
} }
} }