github.com/leeclow-ops/gophercloud@v1.2.1/errors.go (about)

     1  package gophercloud
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strings"
     7  )
     8  
     9  // BaseError is an error type that all other error types embed.
    10  type BaseError struct {
    11  	DefaultErrString string
    12  	Info             string
    13  }
    14  
    15  func (e BaseError) Error() string {
    16  	e.DefaultErrString = "An error occurred while executing a Gophercloud request."
    17  	return e.choseErrString()
    18  }
    19  
    20  func (e BaseError) choseErrString() string {
    21  	if e.Info != "" {
    22  		return e.Info
    23  	}
    24  	return e.DefaultErrString
    25  }
    26  
    27  // ErrMissingInput is the error when input is required in a particular
    28  // situation but not provided by the user
    29  type ErrMissingInput struct {
    30  	BaseError
    31  	Argument string
    32  }
    33  
    34  func (e ErrMissingInput) Error() string {
    35  	e.DefaultErrString = fmt.Sprintf("Missing input for argument [%s]", e.Argument)
    36  	return e.choseErrString()
    37  }
    38  
    39  // ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors.
    40  type ErrInvalidInput struct {
    41  	ErrMissingInput
    42  	Value interface{}
    43  }
    44  
    45  func (e ErrInvalidInput) Error() string {
    46  	e.DefaultErrString = fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value)
    47  	return e.choseErrString()
    48  }
    49  
    50  // ErrMissingEnvironmentVariable is the error when environment variable is required
    51  // in a particular situation but not provided by the user
    52  type ErrMissingEnvironmentVariable struct {
    53  	BaseError
    54  	EnvironmentVariable string
    55  }
    56  
    57  func (e ErrMissingEnvironmentVariable) Error() string {
    58  	e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable)
    59  	return e.choseErrString()
    60  }
    61  
    62  // ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables
    63  // is required in a particular situation but not provided by the user
    64  type ErrMissingAnyoneOfEnvironmentVariables struct {
    65  	BaseError
    66  	EnvironmentVariables []string
    67  }
    68  
    69  func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string {
    70  	e.DefaultErrString = fmt.Sprintf(
    71  		"Missing one of the following environment variables [%s]",
    72  		strings.Join(e.EnvironmentVariables, ", "),
    73  	)
    74  	return e.choseErrString()
    75  }
    76  
    77  // ErrUnexpectedResponseCode is returned by the Request method when a response code other than
    78  // those listed in OkCodes is encountered.
    79  type ErrUnexpectedResponseCode struct {
    80  	BaseError
    81  	URL            string
    82  	Method         string
    83  	Expected       []int
    84  	Actual         int
    85  	Body           []byte
    86  	ResponseHeader http.Header
    87  }
    88  
    89  func (e ErrUnexpectedResponseCode) Error() string {
    90  	e.DefaultErrString = fmt.Sprintf(
    91  		"Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s",
    92  		e.Expected, e.Method, e.URL, e.Actual, e.Body,
    93  	)
    94  	return e.choseErrString()
    95  }
    96  
    97  // GetStatusCode returns the actual status code of the error.
    98  func (e ErrUnexpectedResponseCode) GetStatusCode() int {
    99  	return e.Actual
   100  }
   101  
   102  // StatusCodeError is a convenience interface to easily allow access to the
   103  // status code field of the various ErrDefault* types.
   104  //
   105  // By using this interface, you only have to make a single type cast of
   106  // the returned error to err.(StatusCodeError) and then call GetStatusCode()
   107  // instead of having a large switch statement checking for each of the
   108  // ErrDefault* types.
   109  type StatusCodeError interface {
   110  	Error() string
   111  	GetStatusCode() int
   112  }
   113  
   114  // ErrDefault400 is the default error type returned on a 400 HTTP response code.
   115  type ErrDefault400 struct {
   116  	ErrUnexpectedResponseCode
   117  }
   118  
   119  // ErrDefault401 is the default error type returned on a 401 HTTP response code.
   120  type ErrDefault401 struct {
   121  	ErrUnexpectedResponseCode
   122  }
   123  
   124  // ErrDefault403 is the default error type returned on a 403 HTTP response code.
   125  type ErrDefault403 struct {
   126  	ErrUnexpectedResponseCode
   127  }
   128  
   129  // ErrDefault404 is the default error type returned on a 404 HTTP response code.
   130  type ErrDefault404 struct {
   131  	ErrUnexpectedResponseCode
   132  }
   133  
   134  // ErrDefault405 is the default error type returned on a 405 HTTP response code.
   135  type ErrDefault405 struct {
   136  	ErrUnexpectedResponseCode
   137  }
   138  
   139  // ErrDefault408 is the default error type returned on a 408 HTTP response code.
   140  type ErrDefault408 struct {
   141  	ErrUnexpectedResponseCode
   142  }
   143  
   144  // ErrDefault409 is the default error type returned on a 409 HTTP response code.
   145  type ErrDefault409 struct {
   146  	ErrUnexpectedResponseCode
   147  }
   148  
   149  // ErrDefault429 is the default error type returned on a 429 HTTP response code.
   150  type ErrDefault429 struct {
   151  	ErrUnexpectedResponseCode
   152  }
   153  
   154  // ErrDefault500 is the default error type returned on a 500 HTTP response code.
   155  type ErrDefault500 struct {
   156  	ErrUnexpectedResponseCode
   157  }
   158  
   159  // ErrDefault502 is the default error type returned on a 502 HTTP response code.
   160  type ErrDefault502 struct {
   161  	ErrUnexpectedResponseCode
   162  }
   163  
   164  // ErrDefault503 is the default error type returned on a 503 HTTP response code.
   165  type ErrDefault503 struct {
   166  	ErrUnexpectedResponseCode
   167  }
   168  
   169  // ErrDefault504 is the default error type returned on a 504 HTTP response code.
   170  type ErrDefault504 struct {
   171  	ErrUnexpectedResponseCode
   172  }
   173  
   174  func (e ErrDefault400) Error() string {
   175  	e.DefaultErrString = fmt.Sprintf(
   176  		"Bad request with: [%s %s], error message: %s",
   177  		e.Method, e.URL, e.Body,
   178  	)
   179  	return e.choseErrString()
   180  }
   181  func (e ErrDefault401) Error() string {
   182  	return "Authentication failed"
   183  }
   184  func (e ErrDefault403) Error() string {
   185  	e.DefaultErrString = fmt.Sprintf(
   186  		"Request forbidden: [%s %s], error message: %s",
   187  		e.Method, e.URL, e.Body,
   188  	)
   189  	return e.choseErrString()
   190  }
   191  func (e ErrDefault404) Error() string {
   192  	e.DefaultErrString = fmt.Sprintf(
   193  		"Resource not found: [%s %s], error message: %s",
   194  		e.Method, e.URL, e.Body,
   195  	)
   196  	return e.choseErrString()
   197  }
   198  func (e ErrDefault405) Error() string {
   199  	return "Method not allowed"
   200  }
   201  func (e ErrDefault408) Error() string {
   202  	return "The server timed out waiting for the request"
   203  }
   204  func (e ErrDefault429) Error() string {
   205  	return "Too many requests have been sent in a given amount of time. Pause" +
   206  		" requests, wait up to one minute, and try again."
   207  }
   208  func (e ErrDefault500) Error() string {
   209  	return "Internal Server Error"
   210  }
   211  func (e ErrDefault502) Error() string {
   212  	return "Bad Gateway"
   213  }
   214  func (e ErrDefault503) Error() string {
   215  	return "The service is currently unable to handle the request due to a temporary" +
   216  		" overloading or maintenance. This is a temporary condition. Try again later."
   217  }
   218  func (e ErrDefault504) Error() string {
   219  	return "Gateway Timeout"
   220  }
   221  
   222  // Err400er is the interface resource error types implement to override the error message
   223  // from a 400 error.
   224  type Err400er interface {
   225  	Error400(ErrUnexpectedResponseCode) error
   226  }
   227  
   228  // Err401er is the interface resource error types implement to override the error message
   229  // from a 401 error.
   230  type Err401er interface {
   231  	Error401(ErrUnexpectedResponseCode) error
   232  }
   233  
   234  // Err403er is the interface resource error types implement to override the error message
   235  // from a 403 error.
   236  type Err403er interface {
   237  	Error403(ErrUnexpectedResponseCode) error
   238  }
   239  
   240  // Err404er is the interface resource error types implement to override the error message
   241  // from a 404 error.
   242  type Err404er interface {
   243  	Error404(ErrUnexpectedResponseCode) error
   244  }
   245  
   246  // Err405er is the interface resource error types implement to override the error message
   247  // from a 405 error.
   248  type Err405er interface {
   249  	Error405(ErrUnexpectedResponseCode) error
   250  }
   251  
   252  // Err408er is the interface resource error types implement to override the error message
   253  // from a 408 error.
   254  type Err408er interface {
   255  	Error408(ErrUnexpectedResponseCode) error
   256  }
   257  
   258  // Err409er is the interface resource error types implement to override the error message
   259  // from a 409 error.
   260  type Err409er interface {
   261  	Error409(ErrUnexpectedResponseCode) error
   262  }
   263  
   264  // Err429er is the interface resource error types implement to override the error message
   265  // from a 429 error.
   266  type Err429er interface {
   267  	Error429(ErrUnexpectedResponseCode) error
   268  }
   269  
   270  // Err500er is the interface resource error types implement to override the error message
   271  // from a 500 error.
   272  type Err500er interface {
   273  	Error500(ErrUnexpectedResponseCode) error
   274  }
   275  
   276  // Err502er is the interface resource error types implement to override the error message
   277  // from a 502 error.
   278  type Err502er interface {
   279  	Error502(ErrUnexpectedResponseCode) error
   280  }
   281  
   282  // Err503er is the interface resource error types implement to override the error message
   283  // from a 503 error.
   284  type Err503er interface {
   285  	Error503(ErrUnexpectedResponseCode) error
   286  }
   287  
   288  // Err504er is the interface resource error types implement to override the error message
   289  // from a 504 error.
   290  type Err504er interface {
   291  	Error504(ErrUnexpectedResponseCode) error
   292  }
   293  
   294  // ErrTimeOut is the error type returned when an operations times out.
   295  type ErrTimeOut struct {
   296  	BaseError
   297  }
   298  
   299  func (e ErrTimeOut) Error() string {
   300  	e.DefaultErrString = "A time out occurred"
   301  	return e.choseErrString()
   302  }
   303  
   304  // ErrUnableToReauthenticate is the error type returned when reauthentication fails.
   305  type ErrUnableToReauthenticate struct {
   306  	BaseError
   307  	ErrOriginal error
   308  	ErrReauth   error
   309  }
   310  
   311  func (e ErrUnableToReauthenticate) Error() string {
   312  	e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s: %s", e.ErrOriginal, e.ErrReauth)
   313  	return e.choseErrString()
   314  }
   315  
   316  // ErrErrorAfterReauthentication is the error type returned when reauthentication
   317  // succeeds, but an error occurs afterword (usually an HTTP error).
   318  type ErrErrorAfterReauthentication struct {
   319  	BaseError
   320  	ErrOriginal error
   321  }
   322  
   323  func (e ErrErrorAfterReauthentication) Error() string {
   324  	e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal)
   325  	return e.choseErrString()
   326  }
   327  
   328  // ErrServiceNotFound is returned when no service in a service catalog matches
   329  // the provided EndpointOpts. This is generally returned by provider service
   330  // factory methods like "NewComputeV2()" and can mean that a service is not
   331  // enabled for your account.
   332  type ErrServiceNotFound struct {
   333  	BaseError
   334  }
   335  
   336  func (e ErrServiceNotFound) Error() string {
   337  	e.DefaultErrString = "No suitable service could be found in the service catalog."
   338  	return e.choseErrString()
   339  }
   340  
   341  // ErrEndpointNotFound is returned when no available endpoints match the
   342  // provided EndpointOpts. This is also generally returned by provider service
   343  // factory methods, and usually indicates that a region was specified
   344  // incorrectly.
   345  type ErrEndpointNotFound struct {
   346  	BaseError
   347  }
   348  
   349  func (e ErrEndpointNotFound) Error() string {
   350  	e.DefaultErrString = "No suitable endpoint could be found in the service catalog."
   351  	return e.choseErrString()
   352  }
   353  
   354  // ErrResourceNotFound is the error when trying to retrieve a resource's
   355  // ID by name and the resource doesn't exist.
   356  type ErrResourceNotFound struct {
   357  	BaseError
   358  	Name         string
   359  	ResourceType string
   360  }
   361  
   362  func (e ErrResourceNotFound) Error() string {
   363  	e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name)
   364  	return e.choseErrString()
   365  }
   366  
   367  // ErrMultipleResourcesFound is the error when trying to retrieve a resource's
   368  // ID by name and multiple resources have the user-provided name.
   369  type ErrMultipleResourcesFound struct {
   370  	BaseError
   371  	Name         string
   372  	Count        int
   373  	ResourceType string
   374  }
   375  
   376  func (e ErrMultipleResourcesFound) Error() string {
   377  	e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name)
   378  	return e.choseErrString()
   379  }
   380  
   381  // ErrUnexpectedType is the error when an unexpected type is encountered
   382  type ErrUnexpectedType struct {
   383  	BaseError
   384  	Expected string
   385  	Actual   string
   386  }
   387  
   388  func (e ErrUnexpectedType) Error() string {
   389  	e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual)
   390  	return e.choseErrString()
   391  }
   392  
   393  func unacceptedAttributeErr(attribute string) string {
   394  	return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute)
   395  }
   396  
   397  func redundantWithTokenErr(attribute string) string {
   398  	return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute)
   399  }
   400  
   401  func redundantWithUserID(attribute string) string {
   402  	return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute)
   403  }
   404  
   405  // ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
   406  type ErrAPIKeyProvided struct{ BaseError }
   407  
   408  func (e ErrAPIKeyProvided) Error() string {
   409  	return unacceptedAttributeErr("APIKey")
   410  }
   411  
   412  // ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
   413  type ErrTenantIDProvided struct{ BaseError }
   414  
   415  func (e ErrTenantIDProvided) Error() string {
   416  	return unacceptedAttributeErr("TenantID")
   417  }
   418  
   419  // ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
   420  type ErrTenantNameProvided struct{ BaseError }
   421  
   422  func (e ErrTenantNameProvided) Error() string {
   423  	return unacceptedAttributeErr("TenantName")
   424  }
   425  
   426  // ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
   427  type ErrUsernameWithToken struct{ BaseError }
   428  
   429  func (e ErrUsernameWithToken) Error() string {
   430  	return redundantWithTokenErr("Username")
   431  }
   432  
   433  // ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
   434  type ErrUserIDWithToken struct{ BaseError }
   435  
   436  func (e ErrUserIDWithToken) Error() string {
   437  	return redundantWithTokenErr("UserID")
   438  }
   439  
   440  // ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
   441  type ErrDomainIDWithToken struct{ BaseError }
   442  
   443  func (e ErrDomainIDWithToken) Error() string {
   444  	return redundantWithTokenErr("DomainID")
   445  }
   446  
   447  // ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
   448  type ErrDomainNameWithToken struct{ BaseError }
   449  
   450  func (e ErrDomainNameWithToken) Error() string {
   451  	return redundantWithTokenErr("DomainName")
   452  }
   453  
   454  // ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
   455  type ErrUsernameOrUserID struct{ BaseError }
   456  
   457  func (e ErrUsernameOrUserID) Error() string {
   458  	return "Exactly one of Username and UserID must be provided for password authentication"
   459  }
   460  
   461  // ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
   462  type ErrDomainIDWithUserID struct{ BaseError }
   463  
   464  func (e ErrDomainIDWithUserID) Error() string {
   465  	return redundantWithUserID("DomainID")
   466  }
   467  
   468  // ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
   469  type ErrDomainNameWithUserID struct{ BaseError }
   470  
   471  func (e ErrDomainNameWithUserID) Error() string {
   472  	return redundantWithUserID("DomainName")
   473  }
   474  
   475  // ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
   476  // It may also indicate that both a DomainID and a DomainName were provided at once.
   477  type ErrDomainIDOrDomainName struct{ BaseError }
   478  
   479  func (e ErrDomainIDOrDomainName) Error() string {
   480  	return "You must provide exactly one of DomainID or DomainName to authenticate by Username"
   481  }
   482  
   483  // ErrMissingPassword indicates that no password was provided and no token is available.
   484  type ErrMissingPassword struct{ BaseError }
   485  
   486  func (e ErrMissingPassword) Error() string {
   487  	return "You must provide a password to authenticate"
   488  }
   489  
   490  // ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
   491  type ErrScopeDomainIDOrDomainName struct{ BaseError }
   492  
   493  func (e ErrScopeDomainIDOrDomainName) Error() string {
   494  	return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName"
   495  }
   496  
   497  // ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
   498  type ErrScopeProjectIDOrProjectName struct{ BaseError }
   499  
   500  func (e ErrScopeProjectIDOrProjectName) Error() string {
   501  	return "You must provide at most one of ProjectID or ProjectName in a Scope"
   502  }
   503  
   504  // ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
   505  type ErrScopeProjectIDAlone struct{ BaseError }
   506  
   507  func (e ErrScopeProjectIDAlone) Error() string {
   508  	return "ProjectID must be supplied alone in a Scope"
   509  }
   510  
   511  // ErrScopeEmpty indicates that no credentials were provided in a Scope.
   512  type ErrScopeEmpty struct{ BaseError }
   513  
   514  func (e ErrScopeEmpty) Error() string {
   515  	return "You must provide either a Project or Domain in a Scope"
   516  }
   517  
   518  // ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name
   519  type ErrAppCredMissingSecret struct{ BaseError }
   520  
   521  func (e ErrAppCredMissingSecret) Error() string {
   522  	return "You must provide an Application Credential Secret"
   523  }