1 // Package httperror defines the format for HTTP error responses
2 // from Chain services.
9 "github.com/vapor/errors"
10 "github.com/vapor/net/http/httpjson"
13 // Info contains a set of error codes to send to the user.
15 HTTPStatus int `json:"-"`
16 ChainCode string `json:"code"`
17 Message string `json:"msg"`
20 // Response defines the error response for a Chain error.
21 type Response struct {
23 Status string `json:"status,omitempty"`
24 Detail string `json:"detail,omitempty"`
25 Data map[string]interface{} `json:"data,omitempty"`
26 Temporary bool `json:"temporary"`
29 // Formatter defines rules for mapping errors to the Chain error
31 type Formatter struct {
33 IsTemporary func(info Info, err error) bool
37 // Format builds an error Response body describing err by consulting
38 // the f.Errors lookup table. If no entry is found, it returns f.Default.
39 func (f Formatter) Format(err error) (body Response) {
40 root := errors.Root(err)
41 // Some types cannot be used as map keys, for example slices.
42 // If an error's underlying type is one of these, don't panic.
43 // Just treat it like any other missing entry.
45 if err := recover(); err != nil {
46 body = Response{f.Default, "fail", "", nil, true}
49 info, ok := f.Errors[root]
57 Detail: errors.Detail(err),
58 Data: errors.Data(err),
59 Temporary: f.IsTemporary(info, err),
64 // Write writes a json encoded Response to the ResponseWriter.
65 // It uses the status code associated with the error.
67 // Write may be used as an ErrorWriter in the httpjson package.
68 func (f Formatter) Write(ctx context.Context, w http.ResponseWriter, err error) {
70 httpjson.Write(ctx, w, resp.HTTPStatus, resp)