problem

package module
v1.9.1 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2024 License: MIT Imports: 5 Imported by: 17

README

problem

Coverage PkgGoDev Go Report Card

A golang library that implements application/problem+json and application/problem+xml

Features

  • compatible with application/problem+json
  • inspired by https://github.com/zalando/problem
  • RFC link https://tools.ietf.org/html/rfc7807
  • a Problem implements the Error interface and can be compared with errors.Is()
  • Wrap an error to a Problem
  • application/problem+xml is also supported using xml.Unmarshal and xml.Marshal
  • Auto-Title based on StatusCode with problem.Of(statusCode)

Install

go get -u schneider.vip/problem

Usage

problem.New(problem.Title("Not Found"), problem.Status(404)).JSONString()

Will produce this:

{
  "status": 404,
  "title": "Not Found"
}

You can also autofill the title based on the StatusCode:

problem.Of(404)

Will produce the same problem as above!

You can also append some more options:

p := problem.Of(http.StatusNotFound)
p.Append(problem.Detail("some more details"))

// Use the Marshaler interface to get the problem json as []byte
jsonBytes, err := json.Marshal(p)

// or simpler (ignores the error)
jsonBytes = p.JSON()

Custom key/values are also supported:

problem.New(problem.Title("Not Found"), problem.Custom("key", "value"))

To write the Problem directly to a http.ResponseWriter:

http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	problem.New(
		problem.Type("https://example.com/404"),
		problem.Status(404),
	).WriteTo(w)
})

Create a Problem from an existing error

_, err := ioutil.ReadFile("non-existing")
if err != nil {
	p := problem.New(
		problem.Wrap(err),
		problem.Title("Internal Error"),
		problem.Status(404),
	)
	if !errors.Is(p, os.ErrNotExist) {
		t.Fatalf("expected not existing error")
	}
}
Gin Framework

If you are using gin you can simply reply the problem to the client:

func(c *gin.Context) {
	problem.New(
		problem.Title("houston! we have a problem"),
		problem.Status(http.StatusNotFound),
	).WriteTo(c.Writer)
}
Echo Framework

If you are using echo you can use the following error handler to handle Problems and return them to client.

func ProblemHandler(err error, c echo.Context) {
	if prb, ok := err.(*problem.Problem); ok {
		if !c.Response().Committed {
			if c.Request().Method == http.MethodHead {
				prb.WriteHeaderTo(c.Response())
			} else if _, err := prb.WriteTo(c.Response()); err != nil {
				c.Logger().Error(err)
			}
		}
	} else {
		c.Echo().DefaultHTTPErrorHandler(err, c)
	}
}

...
// e is an instance of echo.Echo
e.HTTPErrorHandler = ProblemHandler

Documentation

Overview

Package problem implements RFC7807 `application/problem+json` and `application/problem+xml` using the functional options paradigm.

Features

- Compatible with `application/problem+json`. - Inspired by https://github.com/zalando/problem. - RFC link https://tools.ietf.org/html/rfc7807. - A Problem implements the Error interface and can be compared with errors.Is(). - Wrap an error to a Problem. - `application/problem+xml` is also supported using `xml.Unmarshal` and `xml.Marshal`. - Auto-Title based on StatusCode with `problem.Of(statusCode)`.

Installation

To install the package, run:

go get -u schneider.vip/problem

Index

Constants

View Source
const (
	// ContentTypeJSON https://tools.ietf.org/html/rfc7807#section-6.1
	ContentTypeJSON = "application/problem+json"
	// ContentTypeXML https://tools.ietf.org/html/rfc7807#section-6.2
	ContentTypeXML = "application/problem+xml"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option interface {
	// contains filtered or unexported methods
}

An Option configures a Problem using the functional options paradigm popularized by Rob Pike.

func Custom

func Custom(key string, value interface{}) Option

Custom sets a custom key value

func Detail

func Detail(detail string) Option

Detail A human readable explanation specific to this occurrence of the problem.

func Detailf added in v1.8.0

func Detailf(format string, values ...interface{}) Option

Detailf A human readable explanation using a format string specific to this occurrence of the problem.

func Instance

func Instance(uri string) Option

Instance an absolute URI that identifies the specific occurrence of the problem.

func Instancef added in v1.8.1

func Instancef(format string, values ...interface{}) Option

Instance an absolute URI using a format string that identifies the specific occurrence of the problem.

func Status

func Status(status int) Option

Status sets the HTTP status code generated by the origin server for this occurrence of the problem.

func Title

func Title(title string) Option

Title sets a title that appropriately describes it (think short) Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable

func Titlef added in v1.8.0

func Titlef(format string, values ...interface{}) Option

Titlef sets a title using a format string that appropriately describes it (think short) Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable

func Type

func Type(uri string) Option

Type sets the type URI (typically, with the "http" or "https" scheme) that identifies the problem type. When dereferenced, it SHOULD provide human-readable documentation for the problem type

func Wrap added in v1.3.1

func Wrap(err error) Option

Wrap an error to the Problem

func WrapSilent added in v1.9.0

func WrapSilent(err error) Option

WrapSilent wraps an error inside of the Problem without placing the wrapped error into the problem's JSON body. Useful for cases where the underlying error needs to be preserved but not transmitted to the user.

type Problem

type Problem struct {
	// contains filtered or unexported fields
}

Problem is an RFC7807 error and can be compared with errors.Is()

func New

func New(opts ...Option) *Problem

New generates a new Problem

func Of added in v1.6.0

func Of(statusCode int) *Problem

Of creates a Problem based on StatusCode with Title automatically set

func (*Problem) Append

func (p *Problem) Append(opts ...Option) *Problem

Append an Option to a existing Problem

func (Problem) Error added in v1.3.1

func (p Problem) Error() string

Error implements the error interface, so a Problem can be used as an error

func (Problem) Is added in v1.3.1

func (p Problem) Is(err error) bool

Is compares Problem.Error() with err.Error()

func (Problem) JSON

func (p Problem) JSON() []byte

JSON returns the Problem as json bytes

func (Problem) JSONString

func (p Problem) JSONString() string

JSONString returns the Problem as json string

func (Problem) MarshalJSON added in v1.3.1

func (p Problem) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface

func (Problem) MarshalXML added in v1.5.0

func (p Problem) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML implements the xml.Marshaler interface

func (Problem) UnmarshalJSON added in v1.3.1

func (p Problem) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface

func (*Problem) UnmarshalXML added in v1.5.0

func (p *Problem) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML implements the xml.Unmarshaler interface

func (Problem) Unwrap added in v1.3.1

func (p Problem) Unwrap() error

Unwrap returns the result of calling the Unwrap method on err, if err implements Unwrap. Otherwise, Unwrap returns nil.

func (Problem) WriteHeaderTo added in v1.7.0

func (p Problem) WriteHeaderTo(w http.ResponseWriter)

WriteHeaderTo writes the HTTP headers for the JSON Problem ContentType and the problem's HTTP statuscode. This is suitable for responding to HEAD requests.

func (Problem) WriteTo added in v1.1.0

func (p Problem) WriteTo(w http.ResponseWriter) (int, error)

WriteTo writes the JSON Problem to an HTTP Response Writer using the correct Content-Type and the problem's HTTP statuscode

func (Problem) WriteXMLHeaderTo added in v1.7.0

func (p Problem) WriteXMLHeaderTo(w http.ResponseWriter)

WriteXMLHeaderTo writes the HTTP headers for the XML Problem ContentType and the problem's HTTP statuscode. This is suitable for responding to HEAD requests.

func (Problem) WriteXMLTo added in v1.5.0

func (p Problem) WriteXMLTo(w http.ResponseWriter) (int, error)

WriteXMLTo writes the XML Problem to an HTTP Response Writer using the correct Content-Type and the problem's HTTP statuscode

func (Problem) XML added in v1.5.0

func (p Problem) XML() []byte

XML returns the Problem as json bytes

func (Problem) XMLString added in v1.5.0

func (p Problem) XMLString() string

XMLString returns the Problem as xml

Jump to

Keyboard shortcuts

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