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));
+    }
+  }
 }

Reply via email to