http response tooling written
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type (
|
||||
// ErrorResponse is an error
|
||||
ErrorResponse struct {
|
||||
err error
|
||||
msg string
|
||||
status int
|
||||
}
|
||||
)
|
||||
|
||||
// Constructors
|
||||
|
||||
func Errorf(format string, args ...any) ErrorResponse {
|
||||
return ErrorResponse{
|
||||
err: fmt.Errorf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
func BadRequest() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusBadRequest,
|
||||
}
|
||||
}
|
||||
|
||||
func NotFound() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusNotFound,
|
||||
}
|
||||
}
|
||||
|
||||
func Unauthorized() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusUnauthorized,
|
||||
}
|
||||
}
|
||||
|
||||
func Forbidden() ErrorResponse {
|
||||
return ErrorResponse{
|
||||
status: http.StatusForbidden,
|
||||
}
|
||||
}
|
||||
|
||||
// builder pattern implementation
|
||||
|
||||
func (e ErrorResponse) Msg(msg string) ErrorResponse {
|
||||
e.msg = msg
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Status(status int) ErrorResponse {
|
||||
e.status = status
|
||||
return e
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Wrap(err error) ErrorResponse {
|
||||
e.err = err
|
||||
return e
|
||||
}
|
||||
|
||||
// error implementation
|
||||
|
||||
func (e ErrorResponse) Error() string {
|
||||
parts := make([]string, 0, 3)
|
||||
|
||||
if e.msg != "" {
|
||||
parts = append(parts, e.msg)
|
||||
} else if e.status != 0 {
|
||||
parts = append(parts, fmt.Sprintf("status = %d", e.status))
|
||||
}
|
||||
if e.err != nil {
|
||||
parts = append(parts, e.err.Error())
|
||||
}
|
||||
|
||||
if len(parts) == 0 {
|
||||
return "status = 500"
|
||||
}
|
||||
|
||||
return strings.Join(parts, ": ")
|
||||
}
|
||||
|
||||
func (e ErrorResponse) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// nested response value resolution
|
||||
|
||||
func (e ErrorResponse) getStatus() (int, bool) {
|
||||
if e.status != 0 {
|
||||
return e.status, true
|
||||
}
|
||||
|
||||
ce, ok := getError(e.err)
|
||||
if ok {
|
||||
return ce.getStatus()
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (e ErrorResponse) getMsg() (string, bool) {
|
||||
if e.msg != "" {
|
||||
return e.msg, true
|
||||
}
|
||||
|
||||
ce, ok := getError(e.err)
|
||||
if ok {
|
||||
return ce.getMsg()
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
func getError(err error) (e ErrorResponse, ok bool) {
|
||||
ok = errors.As(err, &e)
|
||||
return e, ok
|
||||
}
|
||||
Reference in New Issue
Block a user