-
Notifications
You must be signed in to change notification settings - Fork 150
/
error.go
97 lines (81 loc) · 2.16 KB
/
error.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 core
import (
"encoding/json"
"fmt"
"strings"
"github.com/scaleway/scaleway-cli/v2/internal/human"
)
// CliError is an all-in-one error structure that can be used in commands to return useful errors to the user.
// CliError implements JSON and human marshaler for a smooth experience.
type CliError struct {
// The original error that triggers this CLI error.
// The Err.String() will be print in red to the user.
Err error
// Message allow to override the red message shown to the use.
// By default we will use Err.String() but in same case you may want to keep Err
// to avoid loosing detail in json output.
Message string
Details string
Hint string
// Code allows to return a sepcific error code from the main binary.
Code int
// Empty tells the marshaler to not print any message for the error
Empty bool
}
func (s *CliError) Error() string {
return s.Err.Error()
}
func (s *CliError) MarshalHuman() (string, error) {
if s.Empty {
return "", nil
}
sections := []string(nil)
if s.Err != nil {
humanError := s.Err
if s.Message != "" {
humanError = fmt.Errorf(s.Message)
}
str, err := human.Marshal(humanError, nil)
if err != nil {
return "", err
}
sections = append(sections, str)
}
if s.Details != "" {
str, err := human.Marshal(human.Capitalize(s.Details), &human.MarshalOpt{Title: "Details"})
if err != nil {
return "", err
}
sections = append(sections, str)
}
if s.Hint != "" {
str, err := human.Marshal(human.Capitalize(s.Hint), &human.MarshalOpt{Title: "Hint"})
if err != nil {
return "", err
}
sections = append(sections, str)
}
return strings.Join(sections, "\n\n"), nil
}
func (s *CliError) MarshalJSON() ([]byte, error) {
if s.Empty {
type emptyRes struct{}
return json.Marshal(&emptyRes{})
}
message := s.Message
if message == "" && s.Err != nil {
message = s.Err.Error()
}
type tmpRes struct {
Message string `json:"message,omitempty"`
Error error `json:"error,omitempty"`
Details string `json:"details,omitempty"`
Hint string `json:"hint,omitempty"`
}
return json.Marshal(&tmpRes{
Message: message,
Error: s.Err,
Details: s.Details,
Hint: s.Hint,
})
}