github.com/sacloud/iaas-api-go@v1.12.0/error.go (about)

     1  // Copyright 2022-2023 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  }