Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# problems
Problems is an RFC-7807 and RFC-9457 compliant library for describing HTTP
errors. For more information see [RFC-9457](https://tools.ietf.org/html/rfc9457),
and it's predecessor [RFC-7807](https://tools.ietf.org/html/rfc7807).
# Problems

Problems is an RFC-7807 and RFC-9457 compliant library for describing HTTP errors.
For more information see [RFC-9457](https://tools.ietf.org/html/rfc9457), and it's predecessor [RFC-7807](https://tools.ietf.org/html/rfc7807).

[![Build Status](https://travis-ci.org/moogar0880/problems.svg?branch=master)](https://travis-ci.org/moogar0880/problems)
[![Go Report Card](https://goreportcard.com/badge/github.com/moogar0880/problems)](https://goreportcard.com/report/github.com/moogar0880/problems)
[![GoDoc](https://godoc.org/github.com/moogar0880/problems?status.svg)](https://godoc.org/github.com/moogar0880/problems)

## Usage

The problems library exposes an assortment of types to aid HTTP service authors
in defining and using HTTP Problem detail resources.

### Predefined Errors

You can define basic Problem details up front by using the `NewStatusProblem`
function

Expand Down Expand Up @@ -39,17 +41,18 @@ Which, when served over HTTP as JSON will look like the following:
```

### Detailed Errors

New errors can also be created a head of time, or on the fly like so:

```go
package main

import "github.com/moogar0880/problems"

func NoSuchUser() *problems.DefaultProblem {
nosuch := problems.NewStatusProblem(404)
nosuch.Detail = "Sorry, that user does not exist."
return nosuch
func NoSuchUser() *problems.Problem {
nosuch := problems.NewStatusProblem(404)
nosuch.Detail = "Sorry, that user does not exist."
return nosuch
}
```

Expand All @@ -65,6 +68,7 @@ Which, when served over HTTP as JSON will look like the following:
```

### Extended Errors

The specification for these HTTP problems was designed to allow for arbitrary
expansion of the problem resources. This can be accomplished through this
library by either embedding the `Problem` struct in your extension type:
Expand All @@ -75,7 +79,7 @@ package main
import "github.com/moogar0880/problems"

type CreditProblem struct {
problems.Problem
problems.Problem

Balance float64 `json:"balance"`
Accounts []string `json:"accounts"`
Expand All @@ -100,24 +104,24 @@ Or by using the `problems.ExtendedProblem` type:
package main

import (
"net/http"
"net/http"

"github.com/moogar0880/problems"
"github.com/moogar0880/problems"
)

type CreditProblemExt struct {
Balance float64 `json:"balance"`
Accounts []string `json:"accounts"`
Balance float64 `json:"balance"`
Accounts []string `json:"accounts"`
}

func main() {
problems.NewExt[CreditProblemExt]().
WithStatus(http.StatusForbidden).
WithDetail("Your account does not have sufficient funds to complete this transaction").
WithExtension(CreditProblemExt{
problems.NewExt[CreditProblemExt]().
WithStatus(http.StatusForbidden).
WithDetail("Your account does not have sufficient funds to complete this transaction").
WithExtension(CreditProblemExt{
Balance: 30,
Accounts: []string{"/account/12345", "/account/67890"},
})
})
}
```

Expand All @@ -129,13 +133,14 @@ Which, when served over HTTP as JSON will look like the following:
"title": "Unauthorized",
"status": 401,
"extensions": {
"balance": 30,
"accounts": ["/account/12345", "/account/67890"]
"balance": 30,
"accounts": ["/account/12345", "/account/67890"]
}
}
```

## Serving Problems

Additionally, RFC-7807 defines two new media types for problem resources,
`application/problem+json"` and `application/problem+xml`. This library defines
those media types as the constants `ProblemMediaType` and
Expand All @@ -149,18 +154,18 @@ functioning `HandlerFunc` that will server that error.
package main

import (
"net/http"
"net/http"

"github.com/moogar0880/problems"
)

var Unauthorized = problems.NewStatusProblem(401)

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/secrets", problems.StatusProblemHandler(Unauthorized))
mux := http.NewServeMux()
mux.HandleFunc("/secrets", problems.ProblemHandler(Unauthorized))

server := http.Server{Handler: mux, Addr: ":8080"}
server.ListenAndServe()
server := http.Server{Handler: mux, Addr: ":8080"}
server.ListenAndServe()
}
```
2 changes: 1 addition & 1 deletion problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func NewStatusProblem(status int) *Problem {
return New().WithTitle(http.StatusText(status)).WithStatus(status)
}

// NewDetailedProblem returns a new DefaultProblem with a Detail string set for
// NewDetailedProblem returns a new Problem with a Detail string set for
// a more detailed explanation of the problem being returned.
func NewDetailedProblem(status int, details string) *Problem {
return NewStatusProblem(status).WithDetail(details)
Expand Down