Files
x/smalltrip/problem/500.go

138 lines
3.8 KiB
Go

package problem
import (
"encoding/xml"
"errors"
"net/http"
"time"
)
func NewInternalError(err error, opts ...Option) InternalServerError {
return InternalServerError{
Problem: NewDetailed(http.StatusInternalServerError, err.Error(), opts...),
Errors: newErrorTree(err).Errors,
error: err,
}
}
type InternalServerError struct {
Problem
Errors []ErrorTree `json:"errors" xml:"errors"`
error error `json:"-" xml:"-"`
}
var _ error = InternalServerError{}
func (p InternalServerError) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p.handler(p).ServeHTTP(w, r)
}
func (p InternalServerError) Error() string {
return p.error.Error()
}
func newErrorTree(err error) ErrorTree {
i := ErrorTree{Detail: err.Error(), Errors: []ErrorTree{}, error: err}
if us, ok := err.(interface{ Unwrap() []error }); ok {
for _, e := range us.Unwrap() {
i.Errors = append(i.Errors, newErrorTree(e))
}
} else if e := errors.Unwrap(err); e != nil {
i.Errors = append(i.Errors, newErrorTree(e))
}
return i
}
type ErrorTree struct {
Detail string `json:"detail" xml:"detail"`
Errors []ErrorTree `json:"errors" xml:"errors"`
XMLName xml.Name `json:"-" xml:"errors"`
error error `json:"-" xml:"-"`
}
var _ error = ErrorTree{}
func (i ErrorTree) Error() string {
return i.error.Error()
}
func NewNotImplemented[T time.Time | time.Duration](retryAfter T, opts ...Option) NotImplemented[T] {
p := NewStatus(http.StatusNotImplemented, opts...)
return NotImplemented[T]{Problem: p, RetryAfter: RetryAfter[T]{time: retryAfter}}
}
type NotImplemented[T time.Time | time.Duration] struct {
Problem
RetryAfter RetryAfter[T] `json:"retryAfter" xml:"retry-after"`
}
func (p NotImplemented[T]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Retry-After", p.RetryAfter.String())
p.handler(p).ServeHTTP(w, r)
}
func NewBadGateway(opts ...Option) BadGateway {
return BadGateway{NewStatus(http.StatusBadGateway, opts...)}
}
type BadGateway struct{ Problem }
func NewServiceUnavailable[T time.Time | time.Duration](retryAfter T, opts ...Option) ServiceUnavailable[T] {
p := NewStatus(http.StatusNotImplemented, opts...)
return ServiceUnavailable[T]{Problem: p, RetryAfter: RetryAfter[T]{time: retryAfter}}
}
type ServiceUnavailable[T time.Time | time.Duration] struct {
Problem
RetryAfter RetryAfter[T] `json:"retryAfter" xml:"retry-after"`
}
func (p ServiceUnavailable[T]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Retry-After", p.RetryAfter.String())
p.handler(p).ServeHTTP(w, r)
}
func NewGatewayTimeout(opts ...Option) GatewayTimeout {
return GatewayTimeout{NewStatus(http.StatusGatewayTimeout, opts...)}
}
type GatewayTimeout struct{ Problem }
func NewHTTPVersionNotSupported(opts ...Option) HTTPVersionNotSupported {
return HTTPVersionNotSupported{NewStatus(http.StatusHTTPVersionNotSupported, opts...)}
}
type HTTPVersionNotSupported struct{ Problem }
func NewVariantAlsoNegotiates(opts ...Option) VariantAlsoNegotiates {
return VariantAlsoNegotiates{NewStatus(http.StatusVariantAlsoNegotiates, opts...)}
}
type VariantAlsoNegotiates struct{ Problem }
func NewInsufficientStorage(opts ...Option) InsufficientStorage {
return InsufficientStorage{NewStatus(http.StatusInsufficientStorage, opts...)}
}
type InsufficientStorage struct{ Problem }
func NewLoopDetected(opts ...Option) LoopDetected {
return LoopDetected{NewStatus(http.StatusLoopDetected, opts...)}
}
type LoopDetected struct{ Problem }
func NewNotExtended(opts ...Option) NotExtended {
return NotExtended{NewStatus(http.StatusNotExtended, opts...)}
}
type NotExtended struct{ Problem }
func NewNetworkAuthenticationRequired(opts ...Option) NetworkAuthenticationRequired {
return NetworkAuthenticationRequired{NewStatus(http.StatusNetworkAuthenticationRequired, opts...)}
}
type NetworkAuthenticationRequired struct{ Problem }