Skip to content

Commit

Permalink
fix: TypeMismatch error is handled
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziodemaria committed Nov 5, 2024
1 parent 58c3a71 commit 8ad1db4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
26 changes: 17 additions & 9 deletions Sources/Confidence/FlagEvaluation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public enum ErrorCode {
case invalidContext
case flagNotFound
case evaluationError
case typeMismatch
}

struct FlagResolution: Encodable, Decodable, Equatable {
Expand Down Expand Up @@ -68,28 +69,35 @@ extension FlagResolution {
}

let parsedValue = try getValue(path: parsedKey.path, value: value)
let pathValue: T = getTyped(value: parsedValue) ?? defaultValue
let typedValue: T? = getTyped(value: parsedValue)
let resolveReason = (resolvedFlag.resolveReason == .match && self.context != context)
? .stale
: resolvedFlag.resolveReason

if resolvedFlag.resolveReason == .match {
var resolveReason: ResolveReason = .match
if self.context != context {
resolveReason = .stale
}
if let typedValue = typedValue {
return Evaluation(
value: pathValue,
value: typedValue,
variant: resolvedFlag.variant,
reason: resolveReason,
errorCode: nil,
errorMessage: nil
)
} else {
} else if parsedValue == .init(null: ()) {
return Evaluation(
value: defaultValue,
variant: resolvedFlag.variant,
reason: resolvedFlag.resolveReason,
reason: resolveReason,
errorCode: nil,
errorMessage: nil
)
} else {
return Evaluation(
value: defaultValue,
variant: nil,
reason: .error,
errorCode: .typeMismatch,
errorMessage: nil
)
}
} catch {
return Evaluation(
Expand Down
2 changes: 2 additions & 0 deletions Sources/ConfidenceProvider/ConfidenceFeatureProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ extension Evaluation {
throw OpenFeatureError.flagNotFoundError(key: self.errorMessage ?? "unknown key")
case .evaluationError:
throw OpenFeatureError.generalError(message: self.errorMessage ?? "unknown error")
case .typeMismatch:
throw OpenFeatureError.typeMismatchError
}
}
return ProviderEvaluation(
Expand Down
2 changes: 1 addition & 1 deletion Tests/ConfidenceTests/ConfidenceIntegrationTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ConfidenceIntegrationTests: XCTestCase {
.withContext(initialContext: ctx)
.build()
try await confidence.fetchAndActivate()
let intResult = confidence.getEvaluation(key: "\(resolveFlag).my-integer", defaultValue: "1")
let intResult = confidence.getEvaluation(key: "\(resolveFlag).my-integer", defaultValue: 1)
let boolResult = confidence.getEvaluation(key: "\(resolveFlag).my-boolean", defaultValue: false)


Expand Down
40 changes: 39 additions & 1 deletion Tests/ConfidenceTests/ConfidenceTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class ConfidenceTest: XCTestCase {
let client = FakeClient()
client.resolvedValues = [
ResolvedValue(
value: .init(structure: ["size": .init(integer: 3)]),
value: nil,
flag: "flag",
resolveReason: .noSegmentMatch)
]
Expand Down Expand Up @@ -618,6 +618,44 @@ class ConfidenceTest: XCTestCase {
}
}

func testTypeMismatch() async throws {
class FakeClient: ConfidenceResolveClient {
var resolveStats: Int = 0
var resolvedValues: [ResolvedValue] = []
func resolve(ctx: ConfidenceStruct) async throws -> ResolvesResult {
self.resolveStats += 1
return .init(resolvedValues: resolvedValues, resolveToken: "token")
}
}

let client = FakeClient()
client.resolvedValues = [
ResolvedValue(
variant: "control",
value: .init(structure: ["size": .init(boolean: true)]),
flag: "flag",
resolveReason: .match)
]

let confidence = Confidence.Builder(clientSecret: "test")
.withContext(initialContext: ["targeting_key": .init(string: "user1")])
.withFlagResolverClient(flagResolver: client)
.withFlagApplier(flagApplier: flagApplier)
.build()

try await confidence.fetchAndActivate()
let evaluation = confidence.getEvaluation(
key: "flag.size",
defaultValue: 1)

XCTAssertEqual(client.resolveStats, 1)
XCTAssertEqual(evaluation.value, 1)
XCTAssertEqual(evaluation.errorCode, .typeMismatch)
XCTAssertNil(evaluation.errorMessage, "")
XCTAssertEqual(evaluation.reason, .error)
XCTAssertEqual(evaluation.variant, nil)
}

func testConcurrentActivate() async {
for _ in 1...100 {
Task {
Expand Down

0 comments on commit 8ad1db4

Please sign in to comment.