2017-05-31 16:29:03 +03:00
|
|
|
// Package errors provides a way to return detailed information
|
|
|
|
// for an RPC request error. The error is normally JSON encoded.
|
2015-01-14 02:31:27 +03:00
|
|
|
package errors
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2017-05-31 16:29:03 +03:00
|
|
|
"fmt"
|
2015-01-14 02:31:27 +03:00
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// Error implements the error interface.
|
2015-01-14 02:31:27 +03:00
|
|
|
type Error struct {
|
|
|
|
Id string `json:"id"`
|
|
|
|
Code int32 `json:"code"`
|
|
|
|
Detail string `json:"detail"`
|
|
|
|
Status string `json:"status"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) Error() string {
|
|
|
|
b, _ := json.Marshal(e)
|
|
|
|
return string(b)
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// New generates a custom error.
|
2015-01-14 02:31:27 +03:00
|
|
|
func New(id, detail string, code int32) error {
|
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: code,
|
|
|
|
Detail: detail,
|
|
|
|
Status: http.StatusText(int(code)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// Parse tries to parse a JSON string into an error. If that
|
|
|
|
// fails, it will set the given string as the error detail.
|
2015-01-14 02:31:27 +03:00
|
|
|
func Parse(err string) *Error {
|
2015-01-30 17:51:16 +03:00
|
|
|
e := new(Error)
|
|
|
|
errr := json.Unmarshal([]byte(err), e)
|
2015-01-14 02:31:27 +03:00
|
|
|
if errr != nil {
|
|
|
|
e.Detail = err
|
|
|
|
}
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// BadRequest generates a 400 error.
|
|
|
|
func BadRequest(id, format string, a ...interface{}) error {
|
2015-01-14 02:31:27 +03:00
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 400,
|
2017-05-31 16:29:03 +03:00
|
|
|
Detail: fmt.Sprintf(format, a...),
|
2015-01-14 02:31:27 +03:00
|
|
|
Status: http.StatusText(400),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// Unauthorized generates a 401 error.
|
|
|
|
func Unauthorized(id, format string, a ...interface{}) error {
|
2015-01-14 02:31:27 +03:00
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 401,
|
2017-05-31 16:29:03 +03:00
|
|
|
Detail: fmt.Sprintf(format, a...),
|
2015-01-14 02:31:27 +03:00
|
|
|
Status: http.StatusText(401),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// Forbidden generates a 403 error.
|
|
|
|
func Forbidden(id, format string, a ...interface{}) error {
|
2015-01-14 02:31:27 +03:00
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 403,
|
2017-05-31 16:29:03 +03:00
|
|
|
Detail: fmt.Sprintf(format, a...),
|
2015-01-14 02:31:27 +03:00
|
|
|
Status: http.StatusText(403),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// NotFound generates a 404 error.
|
|
|
|
func NotFound(id, format string, a ...interface{}) error {
|
2015-01-14 02:31:27 +03:00
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 404,
|
2017-05-31 16:29:03 +03:00
|
|
|
Detail: fmt.Sprintf(format, a...),
|
2015-01-14 02:31:27 +03:00
|
|
|
Status: http.StatusText(404),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:29:03 +03:00
|
|
|
// InternalServerError generates a 500 error.
|
|
|
|
func InternalServerError(id, format string, a ...interface{}) error {
|
2015-01-14 02:31:27 +03:00
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 500,
|
2017-05-31 16:29:03 +03:00
|
|
|
Detail: fmt.Sprintf(format, a...),
|
2015-01-14 02:31:27 +03:00
|
|
|
Status: http.StatusText(500),
|
|
|
|
}
|
|
|
|
}
|
2018-02-11 16:51:33 +03:00
|
|
|
|
|
|
|
// Conflict generates a 409 error.
|
|
|
|
func Conflict(id, format string, a ...interface{}) error {
|
|
|
|
return &Error{
|
|
|
|
Id: id,
|
|
|
|
Code: 409,
|
|
|
|
Detail: fmt.Sprintf(format, a...),
|
|
|
|
Status: http.StatusText(409),
|
|
|
|
}
|
|
|
|
}
|