error.go raw

   1  // Copyright 2022-2025 The sacloud/api-client-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 client
  16  
  17  import (
  18  	"errors"
  19  	"fmt"
  20  	"net/http"
  21  )
  22  
  23  // APIError APIコール時のエラーを表す型。各APIクライアントでこれをラップして利用する
  24  type APIError struct {
  25  	Code    int
  26  	Message string
  27  	Err     error
  28  }
  29  
  30  func (e *APIError) Error() string {
  31  	if e.Err == nil {
  32  		return fmt.Sprintf("API Error %d - %s", e.Code, e.Message)
  33  	} else {
  34  		return fmt.Sprintf("API Error %d - %s: %s", e.Code, e.Message, e.Err.Error())
  35  	}
  36  }
  37  
  38  func (e *APIError) Unwrap() error {
  39  	return e.Err
  40  }
  41  
  42  func NewAPIError(code int, msg string, err error) *APIError {
  43  	if len(msg) == 0 {
  44  		msg = http.StatusText(code)
  45  		if msg == "" { // client uses 0 for unknown error
  46  			msg = "unknown error"
  47  		}
  48  	}
  49  	return &APIError{
  50  		Code:    code,
  51  		Message: msg,
  52  		Err:     err,
  53  	}
  54  }
  55  
  56  func IsNotFoundError(err error) bool {
  57  	if err == nil {
  58  		return false
  59  	}
  60  
  61  	var apiError *APIError
  62  	if errors.As(err, &apiError) {
  63  		return apiError.Code == http.StatusNotFound
  64  	}
  65  
  66  	return false
  67  }
  68