httpsyproblem

package module
v0.0.0-...-6bdd580 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2022 License: ISC Imports: 7 Imported by: 1

README

DEPRECATED

Use https://github.com/askeladdk/hproblem instead.

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

View Source
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
	StatusUnauthorized                  = Wrap(401, nil) // RFC 7235, 3.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
	StatusUnavailableForLegalReasons    = Wrap(451, nil) // RFC 7725, 3
	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
	StatusServiceUnavailable            = Wrap(503, nil) // RFC 7231, 6.6.4
	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

func StatusCode(err error) int

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

func Wrap(code int, err error) error

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

func Wrapf

func Wrapf(code int, format string, a ...interface{}) error

Wrapf is a shorthand for wrapping the result of fmt.Errorf.

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

func New(code int, err error) *Details

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) Error

func (details *Details) Error() string

Error implements the error interface and returns the Title field.

func (*Details) StatusCode

func (details *Details) StatusCode() int

StatusCode implements the interface used by StatusCode.

func (*Details) Unwrap

func (details *Details) Unwrap() error

Unwrap implements the interface used by errors.Unwrap() and returns the wrapped error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL