Skip to content

Instantly share code, notes, and snippets.

@finestructure
Last active February 26, 2025 09:23
Show Gist options
  • Save finestructure/8ee3ce87ba7cb70ac97f14a5229f4eae to your computer and use it in GitHub Desktop.
Save finestructure/8ee3ce87ba7cb70ac97f14a5229f4eae to your computer and use it in GitHub Desktop.
#expect issues with throws

I have a test that I initially converted as follows to Swift Testing:

    @Test func S3Store_Key_readme() throws {
        withDependencies {
            $0.environment.awsReadmeBucket = { "readme-bucket" }
        } operation: {
            #expect(try S3Store.Key.readme(owner: "foo", repository: "bar").path == "foo/bar/readme.html")
            #expect(try S3Store.Key.readme(owner: "FOO", repository: "bar").path == "foo/bar/readme.html")
        }
    }

where withDependencies is from swift-dependencies with the following signature:

@discardableResult
public func withDependencies<R>(
  _ updateValuesForOperation: (inout DependencyValues) throws -> Void,
  operation: () throws -> R
) rethrows -> R

This does not compile, with an error raised in the macro code:

Errors thrown from here are not handled

Which makes sense, because I'm using withDepenendencies, not try withDependencies.

However, if I do that, I get a warning

No calls to throwing functions occur within 'try' expression

which is not ideal. I can write try #expect(...) but that just moves the warning around.

The only error/warning-free way of writing this to write operation: { () throws in ...:

    @Test func S3Store_Key_readme() throws {
        try withDependencies {
            $0.environment.awsReadmeBucket = { "readme-bucket" }
        } operation: { () throws in
            #expect(try S3Store.Key.readme(owner: "foo", repository: "bar").path == "foo/bar/readme.html")
            #expect(try S3Store.Key.readme(owner: "FOO", repository: "bar").path == "foo/bar/readme.html")
        }
    }

Is this the recommended way of dealing with this problem?

It stumped me for a good moment what the macro error is about and I'm wondering if there's a better solution or maybe even a way to avoid the problem entirely. I don't think I'd have figured this out if I hadn't seen similar issues around async closures with non-asyn overloads that needed the same disambiguation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment