github.com/gophercloud/gophercloud@v1.11.0/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  func (e ErrDefault400) Unwrap() error {
   120  	return e.ErrUnexpectedResponseCode
   121  }
   122  
   123  // ErrDefault401 is the default error type returned on a 401 HTTP response code.
   124  type ErrDefault401 struct {
   125  	ErrUnexpectedResponseCode
   126  }
   127  
   128  func (e ErrDefault401) Unwrap() error {
   129  	return e.ErrUnexpectedResponseCode
   130  }
   131  
   132  // ErrDefault403 is the default error type returned on a 403 HTTP response code.
   133  type ErrDefault403 struct {
   134  	ErrUnexpectedResponseCode
   135  }
   136  
   137  func (e ErrDefault403) Unwrap() error {
   138  	return e.ErrUnexpectedResponseCode
   139  }
   140  
   141  // ErrDefault404 is the default error type returned on a 404 HTTP response code.
   142  type ErrDefault404 struct {
   143  	ErrUnexpectedResponseCode
   144  }
   145  
   146  func (e ErrDefault404) Unwrap() error {
   147  	return e.ErrUnexpectedResponseCode
   148  }
   149  
   150  // ErrDefault405 is the default error type returned on a 405 HTTP response code.
   151  type ErrDefault405 struct {
   152  	ErrUnexpectedResponseCode
   153  }
   154  
   155  func (e ErrDefault405) Unwrap() error {
   156  	return e.ErrUnexpectedResponseCode
   157  }
   158  
   159  // ErrDefault408 is the default error type returned on a 408 HTTP response code.
   160  type ErrDefault408 struct {
   161  	ErrUnexpectedResponseCode
   162  }
   163  
   164  func (e ErrDefault408) Unwrap() error {
   165  	return e.ErrUnexpectedResponseCode
   166  }
   167  
   168  // ErrDefault409 is the default error type returned on a 409 HTTP response code.
   169  type ErrDefault409 struct {
   170  	ErrUnexpectedResponseCode
   171  }
   172  
   173  func (e ErrDefault409) Unwrap() error {
   174  	return e.ErrUnexpectedResponseCode
   175  }
   176  
   177  // ErrDefault429 is the default error type returned on a 429 HTTP response code.
   178  type ErrDefault429 struct {
   179  	ErrUnexpectedResponseCode
   180  }
   181  
   182  func (e ErrDefault429) Unwrap() error {
   183  	return e.ErrUnexpectedResponseCode
   184  }
   185  
   186  // ErrDefault500 is the default error type returned on a 500 HTTP response code.
   187  type ErrDefault500 struct {
   188  	ErrUnexpectedResponseCode
   189  }
   190  
   191  func (e ErrDefault500) Unwrap() error {
   192  	return e.ErrUnexpectedResponseCode
   193  }
   194  
   195  // ErrDefault502 is the default error type returned on a 502 HTTP response code.
   196  type ErrDefault502 struct {
   197  	ErrUnexpectedResponseCode
   198  }
   199  
   200  func (e ErrDefault502) Unwrap() error {
   201  	return e.ErrUnexpectedResponseCode
   202  }
   203  
   204  // ErrDefault503 is the default error type returned on a 503 HTTP response code.
   205  type ErrDefault503 struct {
   206  	ErrUnexpectedResponseCode
   207  }
   208  
   209  func (e ErrDefault503) Unwrap() error {
   210  	return e.ErrUnexpectedResponseCode
   211  }
   212  
   213  // ErrDefault504 is the default error type returned on a 504 HTTP response code.
   214  type ErrDefault504 struct {
   215  	ErrUnexpectedResponseCode
   216  }
   217  
   218  func (e ErrDefault504) Unwrap() error {
   219  	return e.ErrUnexpectedResponseCode
   220  }
   221  
   222  func (e ErrDefault400) Error() string {
   223  	e.DefaultErrString = fmt.Sprintf(
   224  		"Bad request with: [%s %s], error message: %s",
   225  		e.Method, e.URL, e.Body,
   226  	)
   227  	return e.choseErrString()
   228  }
   229  func (e ErrDefault401) Error() string {
   230  	return "Authentication failed"
   231  }
   232  func (e ErrDefault403) Error() string {
   233  	e.DefaultErrString = fmt.Sprintf(
   234  		"Request forbidden: [%s %s], error message: %s",
   235  		e.Method, e.URL, e.Body,
   236  	)
   237  	return e.choseErrString()
   238  }
   239  func (e ErrDefault404) Error() string {
   240  	e.DefaultErrString = fmt.Sprintf(
   241  		"Resource not found: [%s %s], error message: %s",
   242  		e.Method, e.URL, e.Body,
   243  	)
   244  	return e.choseErrString()
   245  }
   246  func (e ErrDefault405) Error() string {
   247  	return "Method not allowed"
   248  }
   249  func (e ErrDefault408) Error() string {
   250  	return "The server timed out waiting for the request"
   251  }
   252  func (e ErrDefault429) Error() string {
   253  	return "Too many requests have been sent in a given amount of time. Pause" +
   254  		" requests, wait up to one minute, and try again."
   255  }
   256  func (e ErrDefault500) Error() string {
   257  	return "Internal Server Error"
   258  }
   259  func (e ErrDefault502) Error() string {
   260  	return "Bad Gateway"
   261  }
   262  func (e ErrDefault503) Error() string {
   263  	return "The service is currently unable to handle the request due to a temporary" +
   264  		" overloading or maintenance. This is a temporary condition. Try again later."
   265  }
   266  func (e ErrDefault504) Error() string {
   267  	return "Gateway Timeout"
   268  }
   269  
   270  // Err400er is the interface resource error types implement to override the error message
   271  // from a 400 error.
   272  type Err400er interface {
   273  	Error400(ErrUnexpectedResponseCode) error
   274  }
   275  
   276  // Err401er is the interface resource error types implement to override the error message
   277  // from a 401 error.
   278  type Err401er interface {
   279  	Error401(ErrUnexpectedResponseCode) error
   280  }
   281  
   282  // Err403er is the interface resource error types implement to override the error message
   283  // from a 403 error.
   284  type Err403er interface {
   285  	Error403(ErrUnexpectedResponseCode) error
   286  }
   287  
   288  // Err404er is the interface resource error types implement to override the error message
   289  // from a 404 error.
   290  type Err404er interface {
   291  	Error404(ErrUnexpectedResponseCode) error
   292  }
   293  
   294  // Err405er is the interface resource error types implement to override the error message
   295  // from a 405 error.
   296  type Err405er interface {
   297  	Error405(ErrUnexpectedResponseCode) error
   298  }
   299  
   300  // Err408er is the interface resource error types implement to override the error message
   301  // from a 408 error.
   302  type Err408er interface {
   303  	Error408(ErrUnexpectedResponseCode) error
   304  }
   305  
   306  // Err409er is the interface resource error types implement to override the error message
   307  // from a 409 error.
   308  type Err409er interface {
   309  	Error409(ErrUnexpectedResponseCode) error
   310  }
   311  
   312  // Err429er is the interface resource error types implement to override the error message
   313  // from a 429 error.
   314  type Err429er interface {
   315  	Error429(ErrUnexpectedResponseCode) error
   316  }
   317  
   318  // Err500er is the interface resource error types implement to override the error message
   319  // from a 500 error.
   320  type Err500er interface {
   321  	Error500(ErrUnexpectedResponseCode) error
   322  }
   323  
   324  // Err502er is the interface resource error types implement to override the error message
   325  // from a 502 error.
   326  type Err502er interface {
   327  	Error502(ErrUnexpectedResponseCode) error
   328  }
   329  
   330  // Err503er is the interface resource error types implement to override the error message
   331  // from a 503 error.
   332  type Err503er interface {
   333  	Error503(ErrUnexpectedResponseCode) error
   334  }
   335  
   336  // Err504er is the interface resource error types implement to override the error message
   337  // from a 504 error.
   338  type Err504er interface {
   339  	Error504(ErrUnexpectedResponseCode) error
   340  }
   341  
   342  // ErrTimeOut is the error type returned when an operations times out.
   343  type ErrTimeOut struct {
   344  	BaseError
   345  }
   346  
   347  func (e ErrTimeOut) Error() string {
   348  	e.DefaultErrString = "A time out occurred"
   349  	return e.choseErrString()
   350  }
   351  
   352  // ErrUnableToReauthenticate is the error type returned when reauthentication fails.
   353  type ErrUnableToReauthenticate struct {
   354  	BaseError
   355  	ErrOriginal error
   356  	ErrReauth   error
   357  }
   358  
   359  func (e ErrUnableToReauthenticate) Error() string {
   360  	e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s: %s", e.ErrOriginal, e.ErrReauth)
   361  	return e.choseErrString()
   362  }
   363  
   364  // ErrErrorAfterReauthentication is the error type returned when reauthentication
   365  // succeeds, but an error occurs afterword (usually an HTTP error).
   366  type ErrErrorAfterReauthentication struct {
   367  	BaseError
   368  	ErrOriginal error
   369  }
   370  
   371  func (e ErrErrorAfterReauthentication) Error() string {
   372  	e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal)
   373  	return e.choseErrString()
   374  }
   375  
   376  // ErrServiceNotFound is returned when no service in a service catalog matches
   377  // the provided EndpointOpts. This is generally returned by provider service
   378  // factory methods like "NewComputeV2()" and can mean that a service is not
   379  // enabled for your account.
   380  type ErrServiceNotFound struct {
   381  	BaseError
   382  }
   383  
   384  func (e ErrServiceNotFound) Error() string {
   385  	e.DefaultErrString = "No suitable service could be found in the service catalog."
   386  	return e.choseErrString()
   387  }
   388  
   389  // ErrEndpointNotFound is returned when no available endpoints match the
   390  // provided EndpointOpts. This is also generally returned by provider service
   391  // factory methods, and usually indicates that a region was specified
   392  // incorrectly.
   393  type ErrEndpointNotFound struct {
   394  	BaseError
   395  }
   396  
   397  func (e ErrEndpointNotFound) Error() string {
   398  	e.DefaultErrString = "No suitable endpoint could be found in the service catalog."
   399  	return e.choseErrString()
   400  }
   401  
   402  // ErrResourceNotFound is the error when trying to retrieve a resource's
   403  // ID by name and the resource doesn't exist.
   404  type ErrResourceNotFound struct {
   405  	BaseError
   406  	Name         string
   407  	ResourceType string
   408  }
   409  
   410  func (e ErrResourceNotFound) Error() string {
   411  	e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name)
   412  	return e.choseErrString()
   413  }
   414  
   415  // ErrMultipleResourcesFound is the error when trying to retrieve a resource's
   416  // ID by name and multiple resources have the user-provided name.
   417  type ErrMultipleResourcesFound struct {
   418  	BaseError
   419  	Name         string
   420  	Count        int
   421  	ResourceType string
   422  }
   423  
   424  func (e ErrMultipleResourcesFound) Error() string {
   425  	e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name)
   426  	return e.choseErrString()
   427  }
   428  
   429  // ErrUnexpectedType is the error when an unexpected type is encountered
   430  type ErrUnexpectedType struct {
   431  	BaseError
   432  	Expected string
   433  	Actual   string
   434  }
   435  
   436  func (e ErrUnexpectedType) Error() string {
   437  	e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual)
   438  	return e.choseErrString()
   439  }
   440  
   441  func unacceptedAttributeErr(attribute string) string {
   442  	return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute)
   443  }
   444  
   445  func redundantWithTokenErr(attribute string) string {
   446  	return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute)
   447  }
   448  
   449  func redundantWithUserID(attribute string) string {
   450  	return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute)
   451  }
   452  
   453  // ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
   454  type ErrAPIKeyProvided struct{ BaseError }
   455  
   456  func (e ErrAPIKeyProvided) Error() string {
   457  	return unacceptedAttributeErr("APIKey")
   458  }
   459  
   460  // ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
   461  type ErrTenantIDProvided struct{ BaseError }
   462  
   463  func (e ErrTenantIDProvided) Error() string {
   464  	return unacceptedAttributeErr("TenantID")
   465  }
   466  
   467  // ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
   468  type ErrTenantNameProvided struct{ BaseError }
   469  
   470  func (e ErrTenantNameProvided) Error() string {
   471  	return unacceptedAttributeErr("TenantName")
   472  }
   473  
   474  // ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
   475  type ErrUsernameWithToken struct{ BaseError }
   476  
   477  func (e ErrUsernameWithToken) Error() string {
   478  	return redundantWithTokenErr("Username")
   479  }
   480  
   481  // ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
   482  type ErrUserIDWithToken struct{ BaseError }
   483  
   484  func (e ErrUserIDWithToken) Error() string {
   485  	return redundantWithTokenErr("UserID")
   486  }
   487  
   488  // ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
   489  type ErrDomainIDWithToken struct{ BaseError }
   490  
   491  func (e ErrDomainIDWithToken) Error() string {
   492  	return redundantWithTokenErr("DomainID")
   493  }
   494  
   495  // ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
   496  type ErrDomainNameWithToken struct{ BaseError }
   497  
   498  func (e ErrDomainNameWithToken) Error() string {
   499  	return redundantWithTokenErr("DomainName")
   500  }
   501  
   502  // ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
   503  type ErrUsernameOrUserID struct{ BaseError }
   504  
   505  func (e ErrUsernameOrUserID) Error() string {
   506  	return "Exactly one of Username and UserID must be provided for password authentication"
   507  }
   508  
   509  // ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
   510  type ErrDomainIDWithUserID struct{ BaseError }
   511  
   512  func (e ErrDomainIDWithUserID) Error() string {
   513  	return redundantWithUserID("DomainID")
   514  }
   515  
   516  // ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
   517  type ErrDomainNameWithUserID struct{ BaseError }
   518  
   519  func (e ErrDomainNameWithUserID) Error() string {
   520  	return redundantWithUserID("DomainName")
   521  }
   522  
   523  // ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
   524  // It may also indicate that both a DomainID and a DomainName were provided at once.
   525  type ErrDomainIDOrDomainName struct{ BaseError }
   526  
   527  func (e ErrDomainIDOrDomainName) Error() string {
   528  	return "You must provide exactly one of DomainID or DomainName to authenticate by Username"
   529  }
   530  
   531  // ErrMissingPassword indicates that no password was provided and no token is available.
   532  type ErrMissingPassword struct{ BaseError }
   533  
   534  func (e ErrMissingPassword) Error() string {
   535  	return "You must provide a password to authenticate"
   536  }
   537  
   538  // ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
   539  type ErrScopeDomainIDOrDomainName struct{ BaseError }
   540  
   541  func (e ErrScopeDomainIDOrDomainName) Error() string {
   542  	return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName"
   543  }
   544  
   545  // ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
   546  type ErrScopeProjectIDOrProjectName struct{ BaseError }
   547  
   548  func (e ErrScopeProjectIDOrProjectName) Error() string {
   549  	return "You must provide at most one of ProjectID or ProjectName in a Scope"
   550  }
   551  
   552  // ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
   553  type ErrScopeProjectIDAlone struct{ BaseError }
   554  
   555  func (e ErrScopeProjectIDAlone) Error() string {
   556  	return "ProjectID must be supplied alone in a Scope"
   557  }
   558  
   559  // ErrScopeEmpty indicates that no credentials were provided in a Scope.
   560  type ErrScopeEmpty struct{ BaseError }
   561  
   562  func (e ErrScopeEmpty) Error() string {
   563  	return "You must provide either a Project or Domain in a Scope"
   564  }
   565  
   566  // ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name
   567  type ErrAppCredMissingSecret struct{ BaseError }
   568  
   569  func (e ErrAppCredMissingSecret) Error() string {
   570  	return "You must provide an Application Credential Secret"
   571  }