-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathproblem_details.go
More file actions
70 lines (64 loc) · 1.77 KB
/
problem_details.go
File metadata and controls
70 lines (64 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package httpsuite
import (
"encoding/json"
"net/http"
)
const BlankURL = "about:blank"
// ProblemDetails conforms to RFC 9457, providing a standard format for describing errors in HTTP APIs.
type ProblemDetails struct {
Type string `json:"type"`
Title string `json:"title"`
Status int `json:"status"`
Detail string `json:"detail,omitempty"`
Instance string `json:"instance,omitempty"`
Extensions map[string]interface{} `json:"extensions,omitempty"`
}
// ValidationErrorDetail provides structured details about a single validation error.
type ValidationErrorDetail struct {
Field string `json:"field"`
Message string `json:"message"`
}
// MarshalJSON serializes RFC 9457 extension members at the top level.
func (p ProblemDetails) MarshalJSON() ([]byte, error) {
payload := map[string]any{
"type": p.Type,
"title": p.Title,
"status": p.Status,
}
if p.Detail != "" {
payload["detail"] = p.Detail
}
if p.Instance != "" {
payload["instance"] = p.Instance
}
for key, value := range p.Extensions {
switch key {
case "", "type", "title", "status", "detail", "instance", "extensions":
continue
default:
payload[key] = value
}
}
return json.Marshal(payload)
}
// NewProblemDetails creates a ProblemDetails instance with standard fields.
func NewProblemDetails(status int, problemType, title, detail string) *ProblemDetails {
if status < 100 || status > 599 {
status = http.StatusInternalServerError
}
if problemType == "" {
problemType = BlankURL
}
if title == "" {
title = http.StatusText(status)
if title == "" {
title = "Unknown error"
}
}
return &ProblemDetails{
Type: problemType,
Title: title,
Status: status,
Detail: detail,
}
}