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

Explicitly set optional types conflict with try? in calls to resolver #40

Open
yakovmanshin opened this issue Mar 28, 2021 · 0 comments
Labels
bug Something isn’t working help wanted Extra attention is needed

Comments

@yakovmanshin
Copy link
Owner

The following expression looks valid but always returns nil:

let retrievedValue: Int? = try? resolver.value(for: key)

A number of factors contribute to such an outcome:

  • FeatureFlagResolver’s value(for:) method uses generics, and therefore cannot take advantage of Swift’s type inference—the output type should be specified externally;
  • The same method throws, and calls to it require try, try?, or try!, where try?, which returns an optional, is nearly always the preferred option;
  • At the same time, feature flag values themselves cannot be optional: before returning a retrieved value, the resolver validates it, and throws FeatureFlagResolverError.optionalValuesNotAllowed is it’s an optional;
  • In the expression above, Int? is used to denote try?’s return type (always an optional) but is interpreted by the resolver as the type of the feature flag value;
  • The resolver sees an optional type and throws FeatureFlagResolverError.optionalValuesNotAllowed which is then silenced by try? (i.e. the error is replaced with nil).

This issue only occurs when using try?, and attempting to replace it with a do / try / catch block to inspect the error (see below) does not help in reproducing it: inside a do block, try doesn’t return an optional, so the resolver is not confused about the type.

do {
    let retrievedValue: Int = try resolver.value(for: key)
} catch {
    print(error)
}

Right now, I see no clear solution to the problem, which allows preserve both generics and explicit errors in value(for:).

The following code works properly (and it’s actually used in FeatureFlag). However, the fix is super unintuitive.

let retrievedValue = try? resolver.value(for: key) as Int
@yakovmanshin yakovmanshin added bug Something isn’t working help wanted Extra attention is needed labels Mar 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn’t working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant