diff --git a/pkg/bucket/gcp.go b/pkg/bucket/gcp.go index d315eff168d..36cf8738fa0 100644 --- a/pkg/bucket/gcp.go +++ b/pkg/bucket/gcp.go @@ -3,6 +3,7 @@ package bucket import ( "context" "encoding/json" + "errors" "fmt" "math/rand" "net/http" @@ -38,7 +39,7 @@ func (g gcpBucketClient) Exists() (bool, error) { bucket := gcsClient.Bucket(g.bucket.Spec.Name) _, err = bucket.Attrs(ctx) if err != nil { - if err == storage.ErrBucketNotExist { + if isBucketNotFoundError(err) { return false, nil } // Return true for permission errors - unable to determine if bucket exists @@ -116,7 +117,7 @@ func (g gcpBucketClient) Delete() (bool, error) { // Check if bucket exists first _, err = bucket.Attrs(ctx) if err != nil { - if err == storage.ErrBucketNotExist { + if isBucketNotFoundError(err) { // Bucket doesn't exist - idempotent behavior return true, nil } @@ -486,7 +487,8 @@ func isGCSRetryableError(err error) bool { return false } - if gerr, ok := err.(*googleapi.Error); ok { + var gerr *googleapi.Error + if errors.As(err, &gerr) { switch gerr.Code { case http.StatusTooManyRequests: // Too Many Requests return true @@ -513,16 +515,28 @@ func isGCSRetryableError(err error) bool { return false } +// isBucketNotFoundError reports whether err indicates a GCS bucket does not exist. +// The GCS library may return storage.ErrBucketNotExist directly, wrap it via fmt.Errorf("%w", ...), +// or surface a *googleapi.Error with HTTP 404 — all three must be handled. +func isBucketNotFoundError(err error) bool { + if errors.Is(err, storage.ErrBucketNotExist) { + return true + } + var gerr *googleapi.Error + return errors.As(err, &gerr) && gerr.Code == http.StatusNotFound +} + // handleGCSError provides consistent error handling for GCS operations func handleGCSError(err error, operation string, bucketName string) error { - if err == storage.ErrBucketNotExist { + if errors.Is(err, storage.ErrBucketNotExist) { if operation == "exists" || operation == "delete" { return nil // Expected for these operations } return fmt.Errorf("bucket '%s' not found", bucketName) } - if gerr, ok := err.(*googleapi.Error); ok { + var gerr *googleapi.Error + if errors.As(err, &gerr) { switch gerr.Code { case http.StatusConflict: // Conflict - Bucket already exists if operation == "create" {