This is an automated email from the ASF dual-hosted git repository.
opwvhk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/main by this push:
new 25651dc29 AVRO-3993: [java] Add better exception msgs when writing
invalid enum symnbol (#2945)
25651dc29 is described below
commit 25651dc2909a18e62d8219d2a730bf02040d576f
Author: Gray <[email protected]>
AuthorDate: Tue Jun 11 03:06:02 2024 -0400
AVRO-3993: [java] Add better exception msgs when writing invalid enum
symnbol (#2945)
* Added better exception messages when writing invalid enum symnbol.
* Remove unnecessary import.
* revert local pom changes that werent supposed to go
* improved the comment
* fixed some characters per the validation
---------
Co-authored-by: Gray Watson <[email protected]>
---
.../avro/src/main/java/org/apache/avro/Schema.java | 8 ++++-
.../src/test/java/org/apache/avro/TestSchema.java | 36 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/lang/java/avro/src/main/java/org/apache/avro/Schema.java
b/lang/java/avro/src/main/java/org/apache/avro/Schema.java
index 3120cfd54..2f0711ed4 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/Schema.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/Schema.java
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.DoubleNode;
import com.fasterxml.jackson.databind.node.NullNode;
+import org.apache.avro.path.TracingAvroTypeException;
import org.apache.avro.util.internal.Accessor;
import org.apache.avro.util.internal.Accessor.FieldAccessor;
import org.apache.avro.util.internal.JacksonUtils;
@@ -1113,7 +1114,12 @@ public abstract class Schema extends JsonProperties
implements Serializable {
@Override
public int getEnumOrdinal(String symbol) {
- return ordinals.get(symbol);
+ Integer ordinal = ordinals.get(symbol);
+ if (ordinal == null) {
+ throw new TracingAvroTypeException(
+ new AvroTypeException("enum value '" + symbol + "' is not in the
enum symbol set: " + symbols));
+ }
+ return ordinal;
}
@Override
diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
b/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
index 6c4e35df9..9a3b14ee7 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
@@ -45,6 +45,13 @@ import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.avro.Schema.Field;
import org.apache.avro.Schema.Type;
import org.apache.avro.generic.GenericData;
+import org.apache.avro.generic.GenericData.EnumSymbol;
+import org.apache.avro.generic.GenericData.Record;
+import org.apache.avro.generic.GenericDatumWriter;
+import org.apache.avro.generic.GenericRecord;
+import org.apache.avro.generic.GenericRecordBuilder;
+import org.apache.avro.io.Encoder;
+import org.apache.avro.io.EncoderFactory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -636,4 +643,33 @@ public class TestSchema {
void testParserNullValidate() {
new Schema.Parser((NameValidator)
null).parse("{\"type\":\"record\",\"name\":\"\",\"fields\":[]}"); // Empty name
}
+
+ /**
+ * Tests when a user tries to write a record with an invalid enum symbol
value
+ * that the exception returned is more descriptive than just a NPE or an
+ * incorrect mention of an unspecified non-null field.
+ */
+ @Test
+ void enumWriteUnknownField() throws IOException {
+ Schema schema = Schema.createRecord("record1", "doc", "", false);
+ String goodValue = "HELLO";
+ Schema enumSchema = Schema.createEnum("enum1", "doc", "",
Arrays.asList(goodValue));
+ Field field1 = new Field("field1", enumSchema);
+ schema.setFields(Collections.singletonList(field1));
+
+ GenericDatumWriter<GenericRecord> datumWriter = new
GenericDatumWriter<>(schema);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ Encoder encoder =
EncoderFactory.get().binaryEncoder(byteArrayOutputStream, null);
+ GenericRecordBuilder builder = new GenericRecordBuilder(schema);
+ String badValue = "GOODBYE";
+ builder.set(field1, new EnumSymbol(enumSchema, badValue));
+ Record record = builder.build();
+ try {
+ datumWriter.write(record, encoder);
+ fail("should have thrown");
+ } catch (AvroTypeException ate) {
+ assertTrue(ate.getMessage().contains(goodValue));
+ assertTrue(ate.getMessage().contains(badValue));
+ }
+ }
}