Skip to content

Commit caa99ae

Browse files
committed
feat(flagd-inprocess): Use program flow instead of exceptions for flag not found errors
Exceptions are expensive GOTO statements, and in a performance relevant system not the best to be used for control flow . A FlagNotFound-Error can be expected, but the performance draw backs of exception in this case not. Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
1 parent f74fe5f commit caa99ae

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolver.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.grpc.GrpcStreamConnector;
1313
import dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator;
1414
import dev.openfeature.contrib.providers.flagd.resolver.process.targeting.TargetingRuleException;
15+
import dev.openfeature.sdk.ErrorCode;
1516
import dev.openfeature.sdk.EvaluationContext;
1617
import dev.openfeature.sdk.ImmutableMetadata;
1718
import dev.openfeature.sdk.ProviderEvaluation;
@@ -164,12 +165,18 @@ private <T> ProviderEvaluation<T> resolve(Class<T> type, String key, EvaluationC
164165

165166
// missing flag
166167
if (flag == null) {
167-
throw new FlagNotFoundError("flag: " + key + " not found");
168+
return ProviderEvaluation.<T>builder()
169+
.errorMessage("flag: " + key + " not found")
170+
.errorCode(ErrorCode.FLAG_NOT_FOUND)
171+
.build();
168172
}
169173

170174
// state check
171175
if ("DISABLED".equals(flag.getState())) {
172-
throw new FlagNotFoundError("flag: " + key + " is disabled");
176+
return ProviderEvaluation.<T>builder()
177+
.errorMessage("flag: " + key + " is disabled")
178+
.errorCode(ErrorCode.FLAG_NOT_FOUND)
179+
.build();
173180
}
174181

175182
final String resolvedVariant;

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessResolverTest.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.StorageStateChange;
99
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.file.FileConnector;
1010
import dev.openfeature.contrib.providers.flagd.resolver.process.storage.connector.grpc.GrpcStreamConnector;
11+
import dev.openfeature.sdk.ErrorCode;
1112
import dev.openfeature.sdk.ImmutableContext;
1213
import dev.openfeature.sdk.ImmutableMetadata;
1314
import dev.openfeature.sdk.MutableContext;
@@ -239,10 +240,8 @@ public void missingFlag() throws Exception {
239240
});
240241

241242
// when/then
242-
assertThrows(FlagNotFoundError.class, () -> {
243-
inProcessResolver.booleanEvaluation("missingFlag", false, new ImmutableContext());
244-
245-
});
243+
ProviderEvaluation<Boolean> missingFlag = inProcessResolver.booleanEvaluation("missingFlag", false, new ImmutableContext());
244+
assertEquals(ErrorCode.FLAG_NOT_FOUND, missingFlag.getErrorCode());
246245
}
247246

248247
@Test
@@ -256,9 +255,8 @@ public void disabledFlag() throws Exception {
256255
});
257256

258257
// when/then
259-
assertThrows(FlagNotFoundError.class, () -> {
260-
inProcessResolver.booleanEvaluation("disabledFlag", false, new ImmutableContext());
261-
});
258+
ProviderEvaluation<Boolean> disabledFlag = inProcessResolver.booleanEvaluation("disabledFlag", false, new ImmutableContext());
259+
assertEquals(ErrorCode.FLAG_NOT_FOUND, disabledFlag.getErrorCode());
262260
}
263261

264262
@Test

0 commit comments

Comments
 (0)