Skip to content

Commit 82ca797

Browse files
authored
fix(flagd): improve error messages for validation, if there are multiple errors (#1250)
Signed-off-by: Simon Schrottner <[email protected]>
1 parent 46f0c7b commit 82ca797

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
import java.net.URI;
1515
import java.util.HashMap;
1616
import java.util.Iterator;
17+
import java.util.List;
1718
import java.util.Map;
1819
import java.util.Set;
1920
import java.util.regex.Pattern;
21+
import java.util.stream.Collectors;
2022
import lombok.extern.slf4j.Slf4j;
2123

2224
/** flagd feature flag configuration parser. */
@@ -59,7 +61,11 @@ public static ParsingResult parseString(final String configuration, boolean thro
5961
Set<ValidationMessage> validationMessages = SCHEMA_VALIDATOR.validate(parser.readValueAsTree());
6062

6163
if (!validationMessages.isEmpty()) {
62-
String message = String.format("Invalid flag configuration: %s", validationMessages.toArray());
64+
List<String> distinctMessages = validationMessages.stream()
65+
.map(ValidationMessage::toString)
66+
.distinct()
67+
.collect(Collectors.toList());
68+
String message = String.format("Invalid flag configuration: %s", distinctMessages);
6369
log.warn(message);
6470
if (throwIfInvalid) {
6571
throw new IllegalArgumentException(message);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class TestUtils {
1818
public static final String INVALID_FLAG_SET_METADATA = "flagConfigurations/invalid-flag-set-metadata.json";
1919
public static final String VALID_FLAG_SET_METADATA = "flagConfigurations/valid-flag-set-metadata.json";
2020
public static final String INVALID_CFG = "flagConfigurations/invalid-configuration.json";
21+
public static final String INVALID_FLAG_MULTIPLE_ERRORS = "flagConfigurations/invalid-flag-multiple-errors.json";
2122
public static final String UPDATABLE_FILE = "flagConfigurations/updatableFlags.json";
2223

2324
public static String getFlagsFromResource(final String file) throws IOException {

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.INVALID_CFG;
44
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.INVALID_FLAG;
55
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.INVALID_FLAG_METADATA;
6+
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.INVALID_FLAG_MULTIPLE_ERRORS;
67
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.INVALID_FLAG_SET_METADATA;
78
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.VALID_FLAG_SET_METADATA;
89
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.VALID_LONG;
910
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.VALID_SIMPLE;
1011
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.VALID_SIMPLE_EXTRA_FIELD;
1112
import static dev.openfeature.contrib.providers.flagd.resolver.process.TestUtils.getFlagsFromResource;
13+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1214
import static org.junit.jupiter.api.Assertions.assertEquals;
1315
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
1416
import static org.junit.jupiter.api.Assertions.assertNotNull;
1517
import static org.junit.jupiter.api.Assertions.assertNull;
16-
import static org.junit.jupiter.api.Assertions.assertThrows;
1718

1819
import java.io.IOException;
1920
import java.util.Map;
@@ -135,24 +136,36 @@ void validJsonConfigurationWithFlagMetadataParsing() throws IOException {
135136
@Test
136137
void invalidFlagThrowsError() throws IOException {
137138
String flagString = getFlagsFromResource(INVALID_FLAG);
138-
assertThrows(IllegalArgumentException.class, () -> FlagParser.parseString(flagString, true));
139+
assertThatThrownBy(() -> FlagParser.parseString(flagString, true)).isInstanceOf(IllegalArgumentException.class);
139140
}
140141

141142
@Test
142143
void invalidFlagMetadataThrowsError() throws IOException {
143144
String flagString = getFlagsFromResource(INVALID_FLAG_METADATA);
144-
assertThrows(IllegalArgumentException.class, () -> FlagParser.parseString(flagString, true));
145+
assertThatThrownBy(() -> FlagParser.parseString(flagString, true)).isInstanceOf(IllegalArgumentException.class);
145146
}
146147

147148
@Test
148149
void invalidFlagSetMetadataThrowsError() throws IOException {
149150
String flagString = getFlagsFromResource(INVALID_FLAG_SET_METADATA);
150-
assertThrows(IllegalArgumentException.class, () -> FlagParser.parseString(flagString, true));
151+
assertThatThrownBy(() -> FlagParser.parseString(flagString, true)).isInstanceOf(IllegalArgumentException.class);
151152
}
152153

153154
@Test
154155
void invalidConfigurationsThrowsError() throws IOException {
155156
String flagString = getFlagsFromResource(INVALID_CFG);
156-
assertThrows(IllegalArgumentException.class, () -> FlagParser.parseString(flagString, true));
157+
assertThatThrownBy(() -> FlagParser.parseString(flagString, true)).isInstanceOf(IllegalArgumentException.class);
158+
}
159+
160+
@Test
161+
void invalidWithMulipleErrorsConfigurationsThrowsError() throws IOException {
162+
String flagString = getFlagsFromResource(INVALID_FLAG_MULTIPLE_ERRORS);
163+
assertThatThrownBy(() -> FlagParser.parseString(flagString, true))
164+
.isInstanceOf(IllegalArgumentException.class)
165+
.hasMessageContaining("must be valid to one and only one schema")
166+
.hasMessageContaining("$.flags.myBoolFlag: required property 'defaultVariant' not found")
167+
.hasMessageContaining("$.flags.myBoolFlag: required property 'state' not found")
168+
.hasMessageContaining(
169+
"$.flags.myBoolFlag.metadata.invalid: object found, [string, number, boolean] expected");
157170
}
158171
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "../../../main/resources/flagd/schemas/flags.json",
3+
"flags": {
4+
"myBoolFlag": {
5+
"metadata": {
6+
"string": "string",
7+
"boolean": true,
8+
"float": 1.234,
9+
"invalid": {
10+
"a": "a"
11+
}
12+
}
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)