Documentation ¶
Overview ¶
Package httpsyproblem provides a standard interface for handling API error responses in web applications. It implements RFC 7807 which specifies a way to carry machine-readable details of errors in a HTTP response to avoid the need to define new error response formats for HTTP APIs.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( StatusContinue = Wrap(100, nil) // RFC 7231, 6.2.1 StatusSwitchingProtocols = Wrap(101, nil) // RFC 7231, 6.2.2 StatusProcessing = Wrap(102, nil) // RFC 2518, 10.1 StatusEarlyHints = Wrap(103, nil) // RFC 8297 StatusOK = Wrap(200, nil) // RFC 7231, 6.3.1 StatusCreated = Wrap(201, nil) // RFC 7231, 6.3.2 StatusAccepted = Wrap(202, nil) // RFC 7231, 6.3.3 StatusNonAuthoritativeInfo = Wrap(203, nil) // RFC 7231, 6.3.4 StatusNoContent = Wrap(204, nil) // RFC 7231, 6.3.5 StatusResetContent = Wrap(205, nil) // RFC 7231, 6.3.6 StatusPartialContent = Wrap(206, nil) // RFC 7233, 4.1 StatusMultiStatus = Wrap(207, nil) // RFC 4918, 11.1 StatusAlreadyReported = Wrap(208, nil) // RFC 5842, 7.1 StatusIMUsed = Wrap(226, nil) // RFC 3229, 10.4.1 StatusMultipleChoices = Wrap(300, nil) // RFC 7231, 6.4.1 StatusMovedPermanently = Wrap(301, nil) // RFC 7231, 6.4.2 StatusFound = Wrap(302, nil) // RFC 7231, 6.4.3 StatusSeeOther = Wrap(303, nil) // RFC 7231, 6.4.4 StatusNotModified = Wrap(304, nil) // RFC 7232, 4.1 StatusUseProxy = Wrap(305, nil) // RFC 7231, 6.4.5 StatusTemporaryRedirect = Wrap(307, nil) // RFC 7231, 6.4.7 StatusPermanentRedirect = Wrap(308, nil) // RFC 7538, 3 StatusBadRequest = Wrap(400, nil) // RFC 7231, 6.5.1 StatusPaymentRequired = Wrap(402, nil) // RFC 7231, 6.5.2 StatusForbidden = Wrap(403, nil) // RFC 7231, 6.5.3 StatusNotFound = Wrap(404, nil) // RFC 7231, 6.5.4 StatusMethodNotAllowed = Wrap(405, nil) // RFC 7231, 6.5.5 StatusNotAcceptable = Wrap(406, nil) // RFC 7231, 6.5.6 StatusProxyAuthRequired = Wrap(407, nil) // RFC 7235, 3.2 StatusRequestTimeout = Wrap(408, nil) // RFC 7231, 6.5.7 StatusConflict = Wrap(409, nil) // RFC 7231, 6.5.8 StatusGone = Wrap(410, nil) // RFC 7231, 6.5.9 StatusLengthRequired = Wrap(411, nil) // RFC 7231, 6.5.10 StatusPreconditionFailed = Wrap(412, nil) // RFC 7232, 4.2 StatusRequestEntityTooLarge = Wrap(413, nil) // RFC 7231, 6.5.11 StatusRequestURITooLong = Wrap(414, nil) // RFC 7231, 6.5.12 StatusUnsupportedMediaType = Wrap(415, nil) // RFC 7231, 6.5.13 StatusRequestedRangeNotSatisfiable = Wrap(416, nil) // RFC 7233, 4.4 StatusExpectationFailed = Wrap(417, nil) // RFC 7231, 6.5.14 StatusTeapot = Wrap(418, nil) // RFC 7168, 2.3.3 StatusMisdirectedRequest = Wrap(421, nil) // RFC 7540, 9.1.2 StatusUnprocessableEntity = Wrap(422, nil) // RFC 4918, 11.2 StatusLocked = Wrap(423, nil) // RFC 4918, 11.3 StatusFailedDependency = Wrap(424, nil) // RFC 4918, 11.4 StatusTooEarly = Wrap(425, nil) // RFC 8470, 5.2. StatusUpgradeRequired = Wrap(426, nil) // RFC 7231, 6.5.15 StatusPreconditionRequired = Wrap(428, nil) // RFC 6585, 3 StatusTooManyRequests = Wrap(429, nil) // RFC 6585, 4 StatusRequestHeaderFieldsTooLarge = Wrap(431, nil) // RFC 6585, 5 StatusInternalServerError = Wrap(500, nil) // RFC 7231, 6.6.1 StatusNotImplemented = Wrap(501, nil) // RFC 7231, 6.6.2 StatusBadGateway = Wrap(502, nil) // RFC 7231, 6.6.3 StatusGatewayTimeout = Wrap(504, nil) // RFC 7231, 6.6.5 StatusHTTPVersionNotSupported = Wrap(505, nil) // RFC 7231, 6.6.6 StatusVariantAlsoNegotiates = Wrap(506, nil) // RFC 2295, 8.1 StatusInsufficientStorage = Wrap(507, nil) // RFC 4918, 11.5 StatusLoopDetected = Wrap(508, nil) // RFC 5842, 7.2 StatusNotExtended = Wrap(510, nil) // RFC 2774, 7 StatusNetworkAuthenticationRequired = Wrap(511, nil) // RFC 6585, 6 )
HTTP status codes as registered with IANA. See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
HTTP status codes can be served as errors:
httpsyproblem.Serve(w, r, httpsyproblem.StatusForbidden)
Functions ¶
func Serve ¶ added in v0.0.2
func Serve(w http.ResponseWriter, r *http.Request, err error)
Serve replies to a request by marshaling the error to JSON, XML or plain text depending on the request's Accept header. Note that Serve will panic if marshaling fails. Serve also accepts errors that implement the http.Handler interface, in which case the error is in charge of marshaling itself.
func StatusCode ¶
StatusCode reports the HTTP status code associated with err if it implements the StatusCode() int method, 504 Gateway Timeout if it implements Timeout() bool, 503 Service Unavailable if it implements Temporary() bool, 500 Internal Server Error otherwise, or 200 OK if err is nil. StatusCode will unwrap err to find the most precise status code.
Example ¶
package main import ( "fmt" "io" "net/http" "github.com/askeladdk/httpsyproblem" ) func main() { fmt.Println(httpsyproblem.StatusCode(nil)) fmt.Println(httpsyproblem.StatusCode(io.EOF)) fmt.Println(httpsyproblem.StatusCode(httpsyproblem.Wrap(http.StatusBadRequest, io.EOF))) }
Output: 200 500 400
func Wrap ¶
Wrap associates an error with a status code and wraps it in a Details.
Example ¶
package main import ( "fmt" "io" "net/http" "github.com/askeladdk/httpsyproblem" ) func main() { // Errors are associated with 500 Internal Server Error by default. err := io.EOF fmt.Println(httpsyproblem.StatusCode(err), err) // Wrap any error to associate it with a status code. err = httpsyproblem.Wrap(http.StatusBadRequest, err) fmt.Println(httpsyproblem.StatusCode(err), err) // Wrapping an already wrapped error changes the status code but preserves the details. err = httpsyproblem.Wrap(http.StatusNotFound, err) fmt.Println(httpsyproblem.StatusCode(err), err) fmt.Println(err.(*httpsyproblem.Details).Detail) }
Output: 500 EOF 400 Bad Request 404 Not Found EOF
Types ¶
type Details ¶
type Details struct { // A human-readable explanation specific to this occurrence of the problem. Detail string `json:"detail,omitempty" xml:"detail,omitempty"` // A URI reference that identifies the specific occurrence of the problem. // It may or may not yield further information if dereferenced. Instance string `json:"instance,omitempty" xml:"instance,omitempty"` // The HTTP status code ([RFC7231], Section 6) // generated by the origin server for this occurrence of the problem. Status int `json:"status,omitempty" xml:"status,omitempty"` // A short, human-readable summary of the problem // type. It SHOULD NOT change from occurrence to occurrence of the // problem, except for purposes of localization (e.g., using // proactive content negotiation; see [RFC7231], Section 3.4). Title string `json:"title,omitempty" xml:"title,omitempty"` // A URI reference [RFC3986] that identifies the // problem type. This specification encourages that, when // dereferenced, it provide human-readable documentation for the // problem type (e.g., using HTML [W3C.REC-html5-20141028]). When // this member is not present, its value is assumed to be // "about:blank". Type string `json:"type,omitempty" xml:"type,omitempty"` // XMLName is needed to marshal to XML. XMLName xml.Name `json:"-" xml:"urn:ietf:rfc:7807 problem"` // contains filtered or unexported fields }
Details implements the RFC 7807 model. Additional fields can be added by embedding Details inside another struct.
type MoreDetails struct { httpsyproblem.Details TraceID string `json:"trace_id" xml:"trace_id"` } httpsyproblem.Serve(w, r, MoreDetails{})
func New ¶
New returns a Details with the Detail, Status and Title fields set according to code and err. If code is 0, the result of StatusCode(err) will be used instead.
func (*Details) StatusCode ¶
StatusCode implements the interface used by StatusCode.