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 }