Skip to content

Commit 26264d6

Browse files
authored
perf: avoid using exceptions for flow control (#1074)
## This PR - avoids using error codes as flow control during an evaluation Signed-off-by: Michael Beemer <[email protected]>
1 parent 418409e commit 26264d6

File tree

2 files changed

+44
-26
lines changed

2 files changed

+44
-26
lines changed

packages/server/src/client/internal/open-feature-client.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -294,26 +294,17 @@ export class OpenFeatureClient implements Client {
294294
};
295295

296296
if (evaluationDetails.errorCode) {
297-
throw instantiateErrorByErrorCode(evaluationDetails.errorCode);
297+
const err = instantiateErrorByErrorCode(evaluationDetails.errorCode);
298+
await this.errorHooks(allHooksReversed, hookContext, err, options);
299+
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
298300
}
299301

300302
await this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
301303

302304
return evaluationDetails;
303305
} catch (err: unknown) {
304-
const errorMessage: string = (err as Error)?.message;
305-
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
306-
307306
await this.errorHooks(allHooksReversed, hookContext, err, options);
308-
309-
return {
310-
errorCode,
311-
errorMessage,
312-
value: defaultValue,
313-
reason: StandardResolutionReasons.ERROR,
314-
flagMetadata: Object.freeze({}),
315-
flagKey,
316-
};
307+
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
317308
} finally {
318309
await this.finallyHooks(allHooksReversed, hookContext, options);
319310
}
@@ -407,4 +398,22 @@ export class OpenFeatureClient implements Client {
407398
throw new ProviderFatalError('provider is in an irrecoverable error state');
408399
}
409400
}
401+
402+
private getErrorEvaluationDetails<T extends FlagValue>(
403+
flagKey: string,
404+
defaultValue: T,
405+
err: unknown,
406+
): EvaluationDetails<T> {
407+
const errorMessage: string = (err as Error)?.message;
408+
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
409+
410+
return {
411+
errorCode,
412+
errorMessage,
413+
value: defaultValue,
414+
reason: StandardResolutionReasons.ERROR,
415+
flagMetadata: Object.freeze({}),
416+
flagKey,
417+
};
418+
}
410419
}

packages/web/src/client/internal/open-feature-client.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -249,26 +249,17 @@ export class OpenFeatureClient implements Client {
249249
};
250250

251251
if (evaluationDetails.errorCode) {
252-
throw instantiateErrorByErrorCode(evaluationDetails.errorCode);
252+
const err = instantiateErrorByErrorCode(evaluationDetails.errorCode);
253+
this.errorHooks(allHooksReversed, hookContext, err, options);
254+
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
253255
}
254256

255257
this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
256258

257259
return evaluationDetails;
258260
} catch (err: unknown) {
259-
const errorMessage: string = (err as Error)?.message;
260-
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
261-
262261
this.errorHooks(allHooksReversed, hookContext, err, options);
263-
264-
return {
265-
errorCode,
266-
errorMessage,
267-
value: defaultValue,
268-
reason: StandardResolutionReasons.ERROR,
269-
flagMetadata: Object.freeze({}),
270-
flagKey,
271-
};
262+
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
272263
} finally {
273264
this.finallyHooks(allHooksReversed, hookContext, options);
274265
}
@@ -341,4 +332,22 @@ export class OpenFeatureClient implements Client {
341332
throw new ProviderFatalError('provider is in an irrecoverable error state');
342333
}
343334
}
335+
336+
private getErrorEvaluationDetails<T extends FlagValue>(
337+
flagKey: string,
338+
defaultValue: T,
339+
err: unknown,
340+
): EvaluationDetails<T> {
341+
const errorMessage: string = (err as Error)?.message;
342+
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
343+
344+
return {
345+
errorCode,
346+
errorMessage,
347+
value: defaultValue,
348+
reason: StandardResolutionReasons.ERROR,
349+
flagMetadata: Object.freeze({}),
350+
flagKey,
351+
};
352+
}
344353
}

0 commit comments

Comments
 (0)