generated from calmato/project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
132 lines (117 loc) · 3.47 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package util
import (
"net/http"
"github.com/calmato/gran-book/api/pkg/exception"
"github.com/gin-gonic/gin"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// ErrorResponse - エラーのレスポンス
type ErrorResponse struct {
StatusCode int `json:"status"` // ステータスコード
ErrorCode exception.ErrorCode `json:"code"` // エラーコード
Message string `json:"message"` // エラー概要
Detail string `json:"detail"` // エラー詳細
}
func ErrorHandling(ctx *gin.Context, err error) {
// gRPCコードに変換 (ok: gRPCのレスポンス, ng: その他)
st, ok := status.FromError(err)
if ok {
ec := convertStatusGrpcToHTTP(st)
err = ec.New(err)
}
code, res := getHTTPError(err)
ctx.JSON(code, res)
ctx.Abort()
}
func IsNotFound(err error) bool {
// gRPCコードに変換 (ok: gRPCのレスポンス, ng: その他)
st, ok := status.FromError(err)
if !ok {
return false
}
ec := convertStatusGrpcToHTTP(st)
return ec == exception.ErrNotFound
}
func getHTTPError(err error) (int, *ErrorResponse) {
res := &ErrorResponse{
ErrorCode: getErrorCode(err),
Detail: getError(err),
}
switch getErrorCode(err) {
case exception.ErrInvalidArgument:
res.StatusCode = http.StatusBadRequest
res.Message = "bad request"
case exception.ErrUnauthorized:
res.StatusCode = http.StatusUnauthorized
res.Message = "unauthenticated"
case exception.ErrForbidden:
res.StatusCode = http.StatusForbidden
res.Message = "forbidden"
case exception.ErrNotFound:
res.StatusCode = http.StatusNotFound
res.Message = "not found"
case exception.ErrConflict:
res.StatusCode = http.StatusConflict
res.Message = "conflict"
case exception.ErrPreconditionFailed:
res.StatusCode = http.StatusPreconditionFailed
res.Message = "precondition failed"
case exception.ErrInternal:
res.StatusCode = http.StatusInternalServerError
res.Message = "internal server error"
case exception.ErrNotImplemented:
res.StatusCode = http.StatusNotImplemented
res.Message = "not implemented"
case exception.ErrServiceUnavailable:
res.StatusCode = http.StatusServiceUnavailable
res.Message = "service unavailable"
case exception.ErrGatewayTimeout:
res.StatusCode = http.StatusGatewayTimeout
res.Message = "gateway timeout"
default:
res.StatusCode = http.StatusInternalServerError
res.Message = "unknown"
}
return res.StatusCode, res
}
func convertStatusGrpcToHTTP(st *status.Status) exception.ErrorCode {
switch st.Code() {
case codes.Unknown:
return exception.ErrInternal
case codes.InvalidArgument:
return exception.ErrInvalidArgument
case codes.DeadlineExceeded:
return exception.ErrGatewayTimeout
case codes.NotFound:
return exception.ErrNotFound
case codes.AlreadyExists:
return exception.ErrConflict
case codes.PermissionDenied:
return exception.ErrForbidden
case codes.FailedPrecondition:
return exception.ErrPreconditionFailed
case codes.Unimplemented:
return exception.ErrNotImplemented
case codes.Internal:
return exception.ErrInternal
case codes.Unavailable:
return exception.ErrServiceUnavailable
case codes.Unauthenticated:
return exception.ErrUnauthorized
default:
return exception.ErrInternal
}
}
func getError(err error) string {
if e, ok := err.(exception.CustomError); ok {
return e.Error()
}
return ""
}
func getErrorCode(err error) exception.ErrorCode {
if e, ok := err.(exception.CustomError); ok {
return e.Code()
}
return exception.ErrInternal
}