-
Notifications
You must be signed in to change notification settings - Fork 2
/
problem.go
97 lines (78 loc) · 2.04 KB
/
problem.go
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package digest
import (
"fmt"
"strings"
"github.com/ProtoconNet/mitum2/util/hint"
"github.com/pkg/errors"
)
const (
ProblemMimetype = "application/problem+json; charset=utf-8"
ProblemNamespace = "https://github.com/ProtoconNet/mitum-currency/v3/problems"
DefaultProblemType = "others"
)
var (
ProblemHint = hint.MustNewHint("mitum-currency-problem-v0.0.1")
)
// Problem implements "Problem Details for HTTP
// APIs"<https://tools.ietf.org/html/rfc7807>.
type Problem struct {
t string // NOTE http problem type
title string
detail string
extra map[string]interface{}
}
func NewProblem(t, title string) Problem {
return Problem{t: t, title: title}
}
func NewProblemFromError(err error) Problem {
title, detail := makeSplitedError(err)
return Problem{
t: DefaultProblemType,
title: fmt.Sprintf("%s", title),
detail: fmt.Sprintf("%+v", detail),
}
}
func (Problem) Hint() hint.Hint {
return ProblemHint
}
func (pr Problem) Error() string {
return pr.title
}
func (pr Problem) SetTitle(title string) Problem {
pr.title = title
return pr
}
func (pr Problem) SetDetail(detail string) Problem {
pr.detail = detail
return pr
}
func (pr Problem) SetExtra(key string, value interface{}) Problem {
if pr.extra == nil {
pr.extra = map[string]interface{}{}
}
pr.extra[key] = value
return pr
}
func makeProblemNamespace(t string) string {
return fmt.Sprintf("%s/%s", ProblemNamespace, t)
}
func parseProblemNamespace(s string) (string, error) {
if !strings.HasPrefix(s, ProblemNamespace) {
return "", errors.Errorf("Invalid problem namespace, %v", s)
}
return s[len(ProblemNamespace)+1:], nil
}
func makeSplitedError(err error) (title, detail string) {
if len(err.Error()) < 1 {
return "", ""
}
errorSlice := strings.Split(err.Error(), ";")
switch {
case len(errorSlice) > 2:
return strings.Join(errorSlice[:len(errorSlice)], ""), errorSlice[len(errorSlice)-1]
case len(errorSlice) < 2:
return errorSlice[0], errorSlice[0]
default:
return strings.TrimSpace(err.Error()), strings.TrimSpace(errorSlice[1])
}
}