-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
120 lines (100 loc) · 2.34 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
package main
import (
"errors"
"fmt"
"net/http"
)
// 에러 분류를 위한 코드
type ErrorCode int
// 에러 분류
const (
UnknownError ErrorCode = iota
NetworkError
EncodingError
)
// 에러 코드와 실제 에러를 포장하는 구조체
type APIError struct {
code ErrorCode
inner error
}
// 에러코드에서 API 에러를 생성한다.
func (code ErrorCode) CreateError(inner error) *APIError {
return &APIError{
code,
inner,
}
}
// APIError의 Unwrap 기능 구현
func (e *APIError) Unwrap() error {
return e.inner
}
// 에러의 문자열 표현
func (e *APIError) Error() string {
message := "알수없는 오류"
switch e.code {
case NetworkError:
message = "네트워크 오류"
case EncodingError:
message = "인코딩 오류"
}
if e.inner != nil {
message = message + ": " + e.inner.Error()
}
return message
}
// 에러에서 http 상태 코드를 알아낸다.
func (e *APIError) getHttpStatusCode() int {
// 해당 목록에 없으면 기본적으로 500 서버 내부 오류
statusCode := http.StatusInternalServerError
switch e.code {
case NetworkError:
statusCode = http.StatusNotFound
case EncodingError:
statusCode = http.StatusBadGateway
}
return statusCode
}
// 에러를 JSON으로 전송하기 위한 타입
type ErrorMessage struct {
StatusCode int `json:"-"`
Message string `json:"error"`
}
/*
에러를 받아 JSON형태 바꾸는 함수
*/
func MakeErrorMessage(err error) ErrorMessage {
// 에러를 분석하고 전송하기 위한 변수
var wrap *APIError
var statusCode int
var message string
// APIError 형식인지 확인하고 아니면 APIError 형식으로 변경한다.
if !errors.As(err, &wrap) {
wrap = UnknownError.CreateError(err)
err = wrap
}
// 필요한 자료를 받아온다.
statusCode = wrap.getHttpStatusCode()
message = err.Error()
// JSON 형식으로 변환한다.
return ErrorMessage{
statusCode,
message,
}
}
/*
해당 에러가 어디에서 일어났는지 표시해주는 함수
명명된 반환 변수(named return value)로 error 타입을 만든 후 defer로 사용해주세요.
ex)
func blahblahfunc() (err error) {
defer WhereInError(&err, "아무튼")
if err = somethingError(); err != nil {
return
}
return
}
*/
func WhereInError(err *error, where string) {
if *err != nil {
*err = fmt.Errorf("%s 오류: %w", where, *err)
}
}