feat(server/apierror): typed Error + sentinels for /api/* envelope
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
package apierror
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
Status int
|
||||
Code string
|
||||
Message string
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
if e.Cause != nil {
|
||||
return fmt.Sprintf("%s: %v", e.Message, e.Cause)
|
||||
}
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func (e *Error) Unwrap() error { return e.Cause }
|
||||
|
||||
// From returns err as *Error if it (or anything in its chain) is one;
|
||||
// otherwise wraps err in an Internal.
|
||||
func From(err error) *Error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var apiErr *Error
|
||||
if errors.As(err, &apiErr) {
|
||||
return apiErr
|
||||
}
|
||||
return Internal(err)
|
||||
}
|
||||
|
||||
func NotFound(what string) *Error {
|
||||
return &Error{Status: 404, Code: what + "_not_found", Message: what + " not found"}
|
||||
}
|
||||
|
||||
func BadRequest(code, message string) *Error {
|
||||
return &Error{Status: 400, Code: code, Message: message}
|
||||
}
|
||||
|
||||
func Conflict(code, message string) *Error {
|
||||
return &Error{Status: 409, Code: code, Message: message}
|
||||
}
|
||||
|
||||
func Forbidden(code, message string) *Error {
|
||||
return &Error{Status: 403, Code: code, Message: message}
|
||||
}
|
||||
|
||||
func Unauthorized(code, message string) *Error {
|
||||
return &Error{Status: 401, Code: code, Message: message}
|
||||
}
|
||||
|
||||
func Internal(cause error) *Error {
|
||||
return &Error{Status: 500, Code: "server_error", Message: "internal server error", Cause: cause}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrNotFound = &Error{Status: 404, Code: "not_found", Message: "not found"}
|
||||
ErrForbidden = &Error{Status: 403, Code: "forbidden", Message: "forbidden"}
|
||||
ErrUnauthorized = &Error{Status: 401, Code: "unauthorized", Message: "authentication required"}
|
||||
)
|
||||
Reference in New Issue
Block a user