Initial QSfera import
This commit is contained in:
+67
@@ -0,0 +1,67 @@
|
||||
// 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{}
|
||||
Reference in New Issue
Block a user