Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/dev/openfeature/sdk/EventDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static EventDetails fromProviderEventDetails(
.flagsChanged(providerEventDetails.getFlagsChanged())
.eventMetadata(providerEventDetails.getEventMetadata())
.message(providerEventDetails.getMessage())
.errorCode(providerEventDetails.getErrorCode())
.build();
}
}
5 changes: 4 additions & 1 deletion src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,10 @@ private void emitError(FeatureProvider provider, OpenFeatureError exception) {
runHandlersForProvider(
provider,
ProviderEvent.PROVIDER_ERROR,
ProviderEventDetails.builder().message(exception.getMessage()).build());
ProviderEventDetails.builder()
.message(exception.getMessage())
.errorCode(exception.getErrorCode())
.build());
}

private void emitErrorAndThrow(FeatureProvider provider, OpenFeatureError exception) throws OpenFeatureError {
Expand Down
53 changes: 53 additions & 0 deletions src/test/java/dev/openfeature/sdk/EventDetailsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dev.openfeature.sdk;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class EventDetailsTest {

@Test
@DisplayName("should carry the error code a provider set, so API-level handlers can see it")
void shouldCopyErrorCode() {
ProviderEventDetails providerEventDetails = ProviderEventDetails.builder()
.errorCode(ErrorCode.PROVIDER_NOT_READY)
.build();

EventDetails details = EventDetails.fromProviderEventDetails(providerEventDetails, "provider");

assertThat(details.getErrorCode()).isEqualTo(ErrorCode.PROVIDER_NOT_READY);
}

@Test
@DisplayName("should leave the error code unset when the provider did not set one")
void shouldLeaveErrorCodeUnsetWhenAbsent() {
EventDetails details = EventDetails.fromProviderEventDetails(
ProviderEventDetails.builder().build(), "provider");

assertThat(details.getErrorCode()).isNull();
}

@Test
@DisplayName("should carry every field of the provider event details")
void shouldCopyEveryField() {
ImmutableMetadata metadata =
ImmutableMetadata.builder().addString("key", "value").build();
ProviderEventDetails providerEventDetails = ProviderEventDetails.builder()
.flagsChanged(Arrays.asList("flag1", "flag2"))
.message("message")
.eventMetadata(metadata)
.errorCode(ErrorCode.GENERAL)
.build();

EventDetails details = EventDetails.fromProviderEventDetails(providerEventDetails, "provider", "domain");

assertThat(details.getFlagsChanged()).isEqualTo(providerEventDetails.getFlagsChanged());
assertThat(details.getMessage()).isEqualTo(providerEventDetails.getMessage());
assertThat(details.getEventMetadata()).isEqualTo(providerEventDetails.getEventMetadata());
assertThat(details.getErrorCode()).isEqualTo(providerEventDetails.getErrorCode());
assertThat(details.getProviderName()).isEqualTo("provider");
assertThat(details.getDomain()).isEqualTo("domain");
}
}
22 changes: 21 additions & 1 deletion src/test/java/dev/openfeature/sdk/EventsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,22 @@ void handlersRunIfOneThrows() {
verify(lastHandler, timeout(TIMEOUT)).accept(any());
}

@Test
@DisplayName("errors the SDK raises itself must carry the error code")
@Specification(
number = "5.1.5",
text = "`PROVIDER_ERROR` events SHOULD populate the `provider event details`'s `error code` field.")
void errorsRaisedBySdkMustCarryErrorCode() {
final Consumer<EventDetails> handler = mockHandler();
api.onProviderError(handler);

api.setProvider(
"errorsRaisedBySdkMustCarryErrorCode", TestProvider.builder().initsToFatal());

verify(handler, timeout(TIMEOUT))
.accept(argThat((EventDetails details) -> ErrorCode.PROVIDER_FATAL.equals(details.getErrorCode())));
}

@Test
@DisplayName("should have all properties")
@Specification(number = "5.2.4", text = "The handler function MUST accept a event details parameter.")
Expand All @@ -561,10 +577,12 @@ void shouldHaveAllProperties() {
ImmutableMetadata metadata =
ImmutableMetadata.builder().addInteger("int", 1).build();
String message = "a message";
ErrorCode errorCode = ErrorCode.GENERAL;
ProviderEventDetails details = ProviderEventDetails.builder()
.eventMetadata(metadata)
.flagsChanged(flagsChanged)
.message(message)
.errorCode(errorCode)
.build();

provider.emit(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details);
Expand All @@ -574,12 +592,14 @@ void shouldHaveAllProperties() {
return metadata.equals(eventDetails.getEventMetadata())
// TODO: issue for client name in events
&& flagsChanged.equals(eventDetails.getFlagsChanged())
&& message.equals(eventDetails.getMessage());
&& message.equals(eventDetails.getMessage())
&& errorCode.equals(eventDetails.getErrorCode());
}));
verify(handler2, timeout(TIMEOUT)).accept(argThat((EventDetails eventDetails) -> {
return metadata.equals(eventDetails.getEventMetadata())
&& flagsChanged.equals(eventDetails.getFlagsChanged())
&& message.equals(eventDetails.getMessage())
&& errorCode.equals(eventDetails.getErrorCode())
&& name.equals(eventDetails.getDomain());
}));
}
Expand Down