Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage functions return different error types #13071

Closed
edonv opened this issue Jun 5, 2024 · 5 comments
Closed

Storage functions return different error types #13071

edonv opened this issue Jun 5, 2024 · 5 comments

Comments

@edonv
Copy link

edonv commented Jun 5, 2024

Description

I've found that different Storage functions return different error types. By this I mean that one action failing throws an NSError while a different one throws a StorageError.

I've tested this at least on the async functions, but they seem to use the same logic under the hood as the Combine and plain callback versions. Here are the things I tested:

  • reference.getMetadata() throws a StorageError.
    • Under the hood, it calls StorageError.swiftConvert(objcError: error as NSError), which internally maps to a StorageError from an NSError generated by the failed call.
  • reference.delete() throws an NSError.
    • Under the hood, it instead calls StorageErrorCode.error(withServerError: error, ref: self.reference), which internally maps an NSError returned by the server call to a new NSError with extra metadata, including the error code.

The main issue here is inconsistency, making it difficult to juggle how I'm supposed to write my catch clause depending on the function call. I don't mind which version is used (though I'd prefer StorageError or a custom Error type that contains the metadata as properties, but it should only be one. Here is how the catch clause differs:

do {
    // `reference` doesn't exist
    try await reference.getMetadata()
    try await reference.delete()
} catch let error as NSError
            where error.code == StorageErrorCode.objectNotFound.rawValue {
    // this successfully catches the error from `delete()`
} catch StorageError.objectNotFound(let errorMessage) {
    // this successfully catches the error from `getMetadata()`
} catch {
    throw error
}

Reproducing the issue

No response

Firebase SDK Version

10.29.0

Xcode Version

15.4

Installation Method

Swift Package Manager

Firebase Product(s)

Storage

Targeted Platforms

iOS

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet
{
  "originHash" : "e7d07dc41236ba3fcaf6b09258b924a0977333c9618f4d7619715b5e61457870",
  "pins" : [
    {
      "identity" : "abseil-cpp-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/abseil-cpp-binary.git",
      "state" : {
        "revision" : "748c7837511d0e6a507737353af268484e1745e2",
        "version" : "1.2024011601.1"
      }
    },
    {
      "identity" : "app-check",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/app-check.git",
      "state" : {
        "revision" : "076b241a625e25eac22f8849be256dfb960fcdfe",
        "version" : "10.19.1"
      }
    },
    {
      "identity" : "appauth-ios",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/openid/AppAuth-iOS.git",
      "state" : {
        "revision" : "c89ed571ae140f8eb1142735e6e23d7bb8c34cb2",
        "version" : "1.7.5"
      }
    },
    {
      "identity" : "asyncbutton",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/AsyncButton",
      "state" : {
        "revision" : "8192bf8f0ccb91fa319f66d99ac49ec20394cec8",
        "version" : "0.0.4"
      }
    },
    {
      "identity" : "collectionconcurrencykit",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
      "state" : {
        "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
        "version" : "0.2.0"
      }
    },
    {
      "identity" : "collectionview",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/collectionview",
      "state" : {
        "revision" : "0a61cd1099c64b0f52ca791292857d755a9e1764",
        "version" : "0.1.2"
      }
    },
    {
      "identity" : "commonextensions",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/CommonExtensions",
      "state" : {
        "revision" : "eb47814882b849a9dd25da5dc717b86bd8905c9a",
        "version" : "0.0.4"
      }
    },
    {
      "identity" : "compositionallayoutbuilder",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/CompositionalLayoutBuilder.git",
      "state" : {
        "revision" : "3bc5fca86756c4dfa375cc9df80414a6f6d37731",
        "version" : "0.0.5"
      }
    },
    {
      "identity" : "documentscannerview",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/DocumentScannerView.git",
      "state" : {
        "revision" : "b278314869450c1ed92d90c5e1f32ddb93673b43",
        "version" : "0.0.6"
      }
    },
    {
      "identity" : "factory",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/hmlongco/Factory",
      "state" : {
        "revision" : "587995f7d5cc667951d635fbf6b4252324ba0439",
        "version" : "2.3.2"
      }
    },
    {
      "identity" : "firebase-ios-sdk",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/firebase-ios-sdk",
      "state" : {
        "revision" : "9d17b500cd98d9a7009751ad62f802e152e97021",
        "version" : "10.26.0"
      }
    },
    {
      "identity" : "googleappmeasurement",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleAppMeasurement.git",
      "state" : {
        "revision" : "16244d177c4e989f87b25e9db1012b382cfedc55",
        "version" : "10.25.0"
      }
    },
    {
      "identity" : "googledatatransport",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleDataTransport.git",
      "state" : {
        "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565",
        "version" : "9.4.0"
      }
    },
    {
      "identity" : "googlesignin-ios",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleSignIn-iOS",
      "state" : {
        "revision" : "a7965d134c5d3567026c523e0a8a583f73b62b0d",
        "version" : "7.1.0"
      }
    },
    {
      "identity" : "googleutilities",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleUtilities.git",
      "state" : {
        "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6",
        "version" : "7.13.3"
      }
    },
    {
      "identity" : "grpc-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/grpc-binary.git",
      "state" : {
        "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359",
        "version" : "1.62.2"
      }
    },
    {
      "identity" : "gtm-session-fetcher",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/gtm-session-fetcher.git",
      "state" : {
        "revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193",
        "version" : "3.4.1"
      }
    },
    {
      "identity" : "gtmappauth",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GTMAppAuth.git",
      "state" : {
        "revision" : "5d7d66f647400952b1758b230e019b07c0b4b22a",
        "version" : "4.1.1"
      }
    },
    {
      "identity" : "interop-ios-for-google-sdks",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/interop-ios-for-google-sdks.git",
      "state" : {
        "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
        "version" : "100.0.0"
      }
    },
    {
      "identity" : "leveldb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/leveldb.git",
      "state" : {
        "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
        "version" : "1.22.5"
      }
    },
    {
      "identity" : "nanopb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/nanopb.git",
      "state" : {
        "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
        "version" : "2.30910.0"
      }
    },
    {
      "identity" : "orother",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/OrOther",
      "state" : {
        "revision" : "5e160eee6a1cb31d6ae5926c60ddb2a3ad282f72",
        "version" : "0.0.5"
      }
    },
    {
      "identity" : "popovers",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/aheze/Popovers",
      "state" : {
        "revision" : "de44c4dd7271ec6413fe350f7efadb14e5e18dce",
        "version" : "1.3.2"
      }
    },
    {
      "identity" : "progressmanager",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/ProgressManager",
      "state" : {
        "revision" : "08656362efb959720c28f6b4afb7bf034415f27d",
        "version" : "0.0.4"
      }
    },
    {
      "identity" : "promises",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/promises.git",
      "state" : {
        "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
        "version" : "2.4.0"
      }
    },
    {
      "identity" : "qlthumbnail",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/QLThumbnail",
      "state" : {
        "revision" : "c4d0aa5423e77eea1d0427f9c58b4b5867941bdd",
        "version" : "0.0.10"
      }
    },
    {
      "identity" : "siren",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/ArtSabintsev/Siren.git",
      "state" : {
        "revision" : "6139af3394bc3635c6c8d5255339796feaa7d1a0",
        "version" : "6.1.3"
      }
    },
    {
      "identity" : "swift-collections",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-collections.git",
      "state" : {
        "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb",
        "version" : "1.1.0"
      }
    },
    {
      "identity" : "swift-protobuf",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-protobuf.git",
      "state" : {
        "revision" : "9f0c76544701845ad98716f3f6a774a892152bcb",
        "version" : "1.26.0"
      }
    },
    {
      "identity" : "swift-syntax",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-syntax.git",
      "state" : {
        "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
        "version" : "509.1.1"
      }
    },
    {
      "identity" : "swiftbackports",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/shaps80/SwiftBackports",
      "state" : {
        "revision" : "ddca6a237c1ba2291d5a3cc47ec8480ce6e9f805",
        "version" : "1.0.3"
      }
    },
    {
      "identity" : "swiftuibackports",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/shaps80/SwiftUIBackports.git",
      "state" : {
        "revision" : "f5f23b016eeda6642a0fe1020241af19c9c05556",
        "version" : "2.8.1"
      }
    },
    {
      "identity" : "swiftuiphpicker",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/SwiftUIPHPicker",
      "state" : {
        "revision" : "f91179f7318805da94e096b87cc938d58aa30383",
        "version" : "0.3.1"
      }
    },
    {
      "identity" : "swiftuiplus",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/shaps80/SwiftUIPlus",
      "state" : {
        "revision" : "acf911dbc22cde80b012f3c41c2c180482e95632",
        "version" : "2.9.0"
      }
    },
    {
      "identity" : "swiftuisharesheet",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/swiftuisharesheet",
      "state" : {
        "revision" : "cc7d3ed4cd436fe4a256f700ce08926d630b9b64",
        "version" : "0.0.1"
      }
    },
    {
      "identity" : "swiftuiwebkit",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/edonv/SwiftUIWebKit.git",
      "state" : {
        "revision" : "165774abbf761aff79781d992968017c13fda05b",
        "version" : "0.0.11"
      }
    },
    {
      "identity" : "swiftuix",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/SwiftUIX/SwiftUIX",
      "state" : {
        "revision" : "ff1176d8c06c2ac81db3dfd36c63ec8a9c2ccbca",
        "version" : "0.2.1"
      }
    },
    {
      "identity" : "textfieldalert",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/sochalewski/TextFieldAlert",
      "state" : {
        "revision" : "f10c8a27cde60e1714f85041501344b916bf557e",
        "version" : "1.4.0"
      }
    }
  ],
  "version" : 3
}

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
Replace this line with the contents of your Podfile.lock!
@google-oss-bot
Copy link

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@edonv
Copy link
Author

edonv commented Jun 5, 2024

Just for fun (and also because I'm using it in my app), I tested the same thing but with updateMetadata(.init()). Again, it's a reference to a file that doesn't exist in Storage. This time, it did send back a StorageError object, but instead of the objectNotFound error case (like in my previous code), it was unauthorized. The documentation implies that it's an issue with my Storage Rules, but I just don't think it should be returning that error case for a non-existent file. The app is still signed into a valid and authenticated Auth user, and the action works fine with a reference to a real file. And I even built an identical request in the Storage Rules Playground and it worked fine pointing to a non-existent file.

@paulb777 paulb777 added this to the Firebase 11 milestone Jun 5, 2024
@paulb777
Copy link
Member

paulb777 commented Jun 5, 2024

Thanks for the report.

We have a bit of mess from trying to balance transitioning to Swift and maintaining backwards compatibility.

We'll see if we can make some improvements in our upcoming major release update.

@edonv
Copy link
Author

edonv commented Jun 6, 2024

Makes sense, thanks! Separately, is Firebase 11 SDK expected to include more Sendable conformance and safety?

@paulb777
Copy link
Member

paulb777 commented Jun 7, 2024

@edonv We don't have near-term plans for more Sendable conformance. The discussion has started for Firestore at #12666. Would you open a separate feature request for any other Firebase classes that you'd like to see prioritized?

@paulb777 paulb777 self-assigned this Jun 13, 2024
@firebase firebase locked and limited conversation to collaborators Jul 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants