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 <beeme1mr@users.noreply.github.com>
This commit is contained in:
Michael Beemer 2024-11-06 16:50:01 -05:00 committed by GitHub
parent 418409e3fa
commit 26264d6d09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 26 deletions

View File

@ -294,26 +294,17 @@ export class OpenFeatureClient implements Client {
}; };
if (evaluationDetails.errorCode) { if (evaluationDetails.errorCode) {
throw instantiateErrorByErrorCode(evaluationDetails.errorCode); const err = instantiateErrorByErrorCode(evaluationDetails.errorCode);
await this.errorHooks(allHooksReversed, hookContext, err, options);
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
} }
await this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options); await this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
return evaluationDetails; return evaluationDetails;
} catch (err: unknown) { } catch (err: unknown) {
const errorMessage: string = (err as Error)?.message;
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
await this.errorHooks(allHooksReversed, hookContext, err, options); await this.errorHooks(allHooksReversed, hookContext, err, options);
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
return {
errorCode,
errorMessage,
value: defaultValue,
reason: StandardResolutionReasons.ERROR,
flagMetadata: Object.freeze({}),
flagKey,
};
} finally { } finally {
await this.finallyHooks(allHooksReversed, hookContext, options); await this.finallyHooks(allHooksReversed, hookContext, options);
} }
@ -407,4 +398,22 @@ export class OpenFeatureClient implements Client {
throw new ProviderFatalError('provider is in an irrecoverable error state'); throw new ProviderFatalError('provider is in an irrecoverable error state');
} }
} }
private getErrorEvaluationDetails<T extends FlagValue>(
flagKey: string,
defaultValue: T,
err: unknown,
): EvaluationDetails<T> {
const errorMessage: string = (err as Error)?.message;
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
return {
errorCode,
errorMessage,
value: defaultValue,
reason: StandardResolutionReasons.ERROR,
flagMetadata: Object.freeze({}),
flagKey,
};
}
} }

View File

@ -249,26 +249,17 @@ export class OpenFeatureClient implements Client {
}; };
if (evaluationDetails.errorCode) { if (evaluationDetails.errorCode) {
throw instantiateErrorByErrorCode(evaluationDetails.errorCode); const err = instantiateErrorByErrorCode(evaluationDetails.errorCode);
this.errorHooks(allHooksReversed, hookContext, err, options);
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
} }
this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options); this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
return evaluationDetails; return evaluationDetails;
} catch (err: unknown) { } catch (err: unknown) {
const errorMessage: string = (err as Error)?.message;
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
this.errorHooks(allHooksReversed, hookContext, err, options); this.errorHooks(allHooksReversed, hookContext, err, options);
return this.getErrorEvaluationDetails(flagKey, defaultValue, err);
return {
errorCode,
errorMessage,
value: defaultValue,
reason: StandardResolutionReasons.ERROR,
flagMetadata: Object.freeze({}),
flagKey,
};
} finally { } finally {
this.finallyHooks(allHooksReversed, hookContext, options); this.finallyHooks(allHooksReversed, hookContext, options);
} }
@ -341,4 +332,22 @@ export class OpenFeatureClient implements Client {
throw new ProviderFatalError('provider is in an irrecoverable error state'); throw new ProviderFatalError('provider is in an irrecoverable error state');
} }
} }
private getErrorEvaluationDetails<T extends FlagValue>(
flagKey: string,
defaultValue: T,
err: unknown,
): EvaluationDetails<T> {
const errorMessage: string = (err as Error)?.message;
const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;
return {
errorCode,
errorMessage,
value: defaultValue,
reason: StandardResolutionReasons.ERROR,
flagMetadata: Object.freeze({}),
flagKey,
};
}
} }