error.go raw
1 // Copyright 2022-2025 The sacloud/iaas-api-go Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package iaas
16
17 import (
18 "errors"
19 "fmt"
20 "net/http"
21 "net/url"
22 )
23
24 // IsNotFoundError 指定のerrorがAPI呼び出し時の404エラーであるか判定
25 func IsNotFoundError(err error) bool {
26 if err == nil {
27 return false
28 }
29
30 if apiError, ok := err.(APIError); ok {
31 return apiError.ResponseCode() == http.StatusNotFound
32 }
33
34 return false
35 }
36
37 // IsNoResultsError 指定のerrorがNoResultErrorであるか判定
38 func IsNoResultsError(err error) bool {
39 if err == nil {
40 return false
41 }
42
43 _, ok := err.(*NoResultsError)
44 return ok
45 }
46
47 // IsStillCreatingError 指定のerrorがAPI呼び出し時の409エラー、かつエラーコードがstill_creatingであるか判定
48 func IsStillCreatingError(err error) bool {
49 if err == nil {
50 return false
51 }
52
53 if apiError, ok := err.(APIError); ok {
54 return apiError.ResponseCode() == http.StatusConflict && apiError.Code() == "still_creating"
55 }
56
57 return false
58 }
59
60 // NoResultsError APIが返した応答に処理すべきデータが含まれていない場合を示すエラー型
61 type NoResultsError struct {
62 error
63 }
64
65 // NewNoResultsError NoResultErrorを返す
66 func NewNoResultsError() *NoResultsError {
67 return &NoResultsError{error: errors.New("no results")}
68 }
69
70 // APIErrorResponse APIエラー型
71 type APIErrorResponse struct {
72 IsFatal bool `json:"is_fatal,omitempty"` // IsFatal
73 Serial string `json:"serial,omitempty"` // Serial
74 Status string `json:"status,omitempty"` // Status
75 ErrorCode string `json:"error_code,omitempty"` // ErrorCode
76 ErrorMessage string `json:"error_msg,omitempty"` // ErrorMessage
77 }
78
79 // APIError APIコール時のエラー情報
80 type APIError interface {
81 // errorインターフェースを内包
82 error
83
84 // エラー発生時のレスポンスコード
85 ResponseCode() int
86
87 // エラーコード
88 Code() string
89
90 // エラー発生時のメッセージ
91 Message() string
92
93 // エラー追跡用シリアルコード
94 Serial() string
95
96 // エラー(オリジナル)
97 OrigErr() *APIErrorResponse
98 }
99
100 // NewAPIError APIコール時のエラー情報
101 func NewAPIError(requestMethod string, requestURL *url.URL, responseCode int, err *APIErrorResponse) APIError {
102 return &apiError{
103 responseCode: responseCode,
104 method: requestMethod,
105 url: requestURL,
106 origErr: err,
107 }
108 }
109
110 type apiError struct {
111 responseCode int
112 method string
113 url *url.URL
114 origErr *APIErrorResponse
115 }
116
117 // Error errorインターフェース
118 func (e *apiError) Error() string {
119 return fmt.Sprintf("Error in response: %#v", e.origErr)
120 }
121
122 // ResponseCode エラー発生時のレスポンスコード
123 func (e *apiError) ResponseCode() int {
124 return e.responseCode
125 }
126
127 // Code エラーコード
128 func (e *apiError) Code() string {
129 if e.origErr != nil {
130 return e.origErr.ErrorCode
131 }
132 return ""
133 }
134
135 // Message エラー発生時のメッセージ
136 func (e *apiError) Message() string {
137 if e.origErr != nil {
138 return e.origErr.ErrorMessage
139 }
140 return ""
141 }
142
143 // Serial エラー追跡用シリアルコード
144 func (e *apiError) Serial() string {
145 if e.origErr != nil {
146 return e.origErr.Serial
147 }
148 return ""
149 }
150
151 // OrigErr エラー(オリジナル)
152 func (e *apiError) OrigErr() *APIErrorResponse {
153 return e.origErr
154 }
155