-
-
Notifications
You must be signed in to change notification settings - Fork 175
/
main.go
110 lines (95 loc) · 2.99 KB
/
main.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
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"github.com/kataras/iris/v12"
// IMPORTANT, import this sub-package.
// Note tht it does NOT break compatibility with the
// standard "errors" package as the New,
// Is, As, Unwrap functions are aliases to the standard package.
"github.com/kataras/iris/v12/x/errors"
)
// Optionally, register custom error codes.
//
// The default list of error code names:
// errors.Cancelled
// errors.Unknown
// errors.InvalidArgument
// errors.DeadlineExceeded
// errors.NotFound
// errors.AlreadyExists
// errors.PermissionDenied
// errors.Unauthenticated
// errors.ResourceExhausted
// errors.FailedPrecondition
// errors.Aborted
// errors.OutOfRange
// errors.Unimplemented
// errors.Internal
// errors.Unavailable
// errors.DataLoss
var (
Custom = errors.Register("CUSTOM_CANONICAL_ERROR_NAME", iris.StatusBadRequest)
)
func main() {
app := iris.New()
// Custom error code name.
app.Get("/custom", fireCustomErrorCodeName)
// Send a simple 400 request with message and an error
// or with more details and data.
app.Post("/invalid_argument", fireInvalidArgument)
// Compatibility with the iris.Problem type (and any other custom type).
app.Get("/problem", fireErrorWithProblem)
app.Listen(":8080")
}
func fireCustomErrorCodeName(ctx iris.Context) {
Custom.Details(ctx, "message", "details with arguments: %s", "an argument")
}
func fireInvalidArgument(ctx iris.Context) {
var req = struct {
Username string `json:"username"`
}{}
if err := ctx.ReadJSON(&req); err != nil {
errors.InvalidArgument.Err(ctx, err)
return
}
ctx.WriteString(req.Username)
// Other examples: errors.InvalidArgument/NotFound/Internal and e.t.c.
// .Message(ctx, "message %s", "optional argument")
// .Details(ctx, "message", "details %s", "optional details argument")
// .Data(ctx, "message", anyTypeOfValue)
// .DataWithDetails(ctx, "unable to read the body", "malformed json", iris.Map{"custom": "data of any type"})
// .Log(ctx, "message %s", "optional argument")
// .LogErr(ctx, err)
}
func fireErrorWithProblem(ctx iris.Context) {
myCondition := true
if myCondition {
problem := iris.NewProblem().
// The type URI, if relative it automatically convert to absolute.
Type("/product-error").
// The title, if empty then it gets it from the status code.
Title("Product validation problem").
// Any optional details.
Detail("details about the product error").
// The status error code of the problem, can be optional here.
// Status(iris.StatusBadRequest).
// Any custom key-value pair.
Key("product_name", "the product name")
errors.InvalidArgument.Data(ctx, "unable to process the request", problem)
return
/* Prints to the client:
{
"http_error_code": {
"canonical_name": "INVALID_ARGUMENT",
"status": 400
},
"message": "unable to process the request",
"data": {
"detail": "details about the product error",
"product_name": "the product name",
"title": "Product validation problem",
"type": "/product-error"
}
}
*/
}
}