mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-19 23:05:04 +01:00
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
// Package httperr implements an error object that speaks HTTP.
|
|
package httperr
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
)
|
|
|
|
// Value is an Error that returns that status and code
|
|
// provided, and reveals the underlying wrapper error to
|
|
// the caller. The text of the error is rendered to the
|
|
// client in the body of the response, as well as in
|
|
// the X-Error header.
|
|
type Value struct {
|
|
Err error // the underlying error
|
|
StatusCode int // the HTTP status code. If not supplied, http.StatusInternalServerError is used.
|
|
Status string // the HTTP status text. If not supplied, http.StatusText(http.StatusCode) is used.
|
|
Public bool
|
|
Header http.Header // extra headers to add to the response (optional)
|
|
}
|
|
|
|
// StatusCodeAndText returns the status code and text of the error
|
|
func (e Value) StatusCodeAndText() (int, string) {
|
|
if e.StatusCode == 0 {
|
|
e.StatusCode = http.StatusInternalServerError
|
|
}
|
|
|
|
if e.Status == "" {
|
|
if e.Err != nil && e.Public {
|
|
e.Status = e.Err.Error()
|
|
} else {
|
|
e.Status = http.StatusText(e.StatusCode)
|
|
}
|
|
}
|
|
|
|
return e.StatusCode, e.Status
|
|
}
|
|
|
|
func (e Value) Error() string {
|
|
statusCode, statusText := StatusCodeAndText(e)
|
|
if e.Public {
|
|
return fmt.Sprintf("%d %s", statusCode, statusText)
|
|
}
|
|
return fmt.Sprintf("%d %s: %s", statusCode, statusText, e.Err.Error())
|
|
}
|
|
|
|
// WriteError writes an error response to w using the specified status code.
|
|
func (e Value) WriteError(w http.ResponseWriter, r *http.Request) {
|
|
for key, values := range e.Header {
|
|
w.Header().Del(key) // overwrite headers already in the response with the ones specified
|
|
for _, value := range values {
|
|
w.Header().Add(key, value)
|
|
}
|
|
}
|
|
|
|
code, message := e.StatusCodeAndText()
|
|
http.Error(w, message, code)
|
|
}
|
|
|
|
// Unwrap unwraps the Value error and returns the underlying error`
|
|
func (e Value) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
var _ error = Value{}
|
|
var _ Writer = Value{}
|
|
var _ statusCodeAndTexter = Value{}
|