httpx: Add new redirect
This commit is contained in:
parent
41d41035e3
commit
8e2d2cce3e
5 changed files with 123 additions and 35 deletions
75
pkg/httpx/errors.go
Normal file
75
pkg/httpx/errors.go
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
package httpx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ErrInterceptor intercepts errors and directly returns specific responses for them
|
||||
type ErrInterceptor struct {
|
||||
Errors map[error]Response
|
||||
Fallback Response
|
||||
}
|
||||
|
||||
// Intercept attempts to intercept the given error.
|
||||
// When err is nil, does nothing.
|
||||
//
|
||||
// When err is not nil, first attempts to find a static response in errors and respond with that.
|
||||
// Otherwise it returns the Fallback response.
|
||||
// intercepted indicates if some response was sent.
|
||||
func (ei ErrInterceptor) Intercept(w http.ResponseWriter, r *http.Request, err error) (intercepted bool) {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
res, ok := ei.Errors[err]
|
||||
if !ok {
|
||||
res = ei.Fallback
|
||||
}
|
||||
|
||||
res.ServerHTTP(w, r)
|
||||
return true
|
||||
}
|
||||
|
||||
// StatusInterceptor creates a new ErrInterceptor handling default responses.
|
||||
// If body returns err != nil, StatusInterceptor calls panic().
|
||||
func StatusInterceptor(contentType string, body func(code int, text string) ([]byte, error)) ErrInterceptor {
|
||||
makeResponse := func(code int) (res Response) {
|
||||
var err error
|
||||
res.Body, err = body(code, http.StatusText(code))
|
||||
if err != nil {
|
||||
panic("StatusInterceptor: err != nil")
|
||||
}
|
||||
|
||||
res.ContentType = contentType
|
||||
res.StatusCode = code
|
||||
return
|
||||
}
|
||||
|
||||
return ErrInterceptor{
|
||||
Errors: map[error]Response{
|
||||
ErrNotFound: makeResponse(http.StatusNotFound),
|
||||
ErrForbidden: makeResponse(http.StatusForbidden),
|
||||
},
|
||||
Fallback: makeResponse(http.StatusInternalServerError),
|
||||
}
|
||||
}
|
||||
|
||||
// Common errors accepted by all httpx handlers
|
||||
var (
|
||||
ErrNotFound = errors.New("httpx: Not Found")
|
||||
ErrForbidden = errors.New("httpx: Forbidden")
|
||||
)
|
||||
|
||||
var (
|
||||
textInterceptor = StatusInterceptor("text/plain", func(code int, text string) ([]byte, error) {
|
||||
return []byte(text), nil
|
||||
})
|
||||
jsonInterceptor = StatusInterceptor("application/json", func(code int, text string) ([]byte, error) {
|
||||
return json.Marshal(map[string]any{"status": text, "code": code})
|
||||
})
|
||||
htmlInterceptor = StatusInterceptor("text/html", func(code int, text string) ([]byte, error) {
|
||||
return []byte(`<!DOCTYPE HTML><title>` + text + `</title>` + text), nil
|
||||
})
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue