This is an automated email from the ASF dual-hosted git repository.

opwvhk pushed a commit to branch branch-1.12
in repository https://gitbox.apache.org/repos/asf/avro.git

commit 2808da09ed99c8e2fc03ae5fa5b4570c518c0fb9
Author: Logan Donoughe <[email protected]>
AuthorDate: Fri May 30 01:16:54 2025 -0700

    AVRO-3791: Include field in readField AvroTypeException (#2420)
    
    In order to bring more clarity and save users time error messages include
    the field avro fails to read. It is now immediately apparent which field
    in a record has issues that need correcting.
    
    (cherry picked from commit 771d824afa5df0eb4afaa651fb2f7ea7b32ba638)
---
 .../src/main/java/org/apache/avro/generic/GenericDatumReader.java | 8 +++++++-
 .../java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java | 5 +++--
 lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java  | 2 +-
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git 
a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java 
b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
index b818a070c1..a47fac0c48 100644
--- 
a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
+++ 
b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 
 import org.apache.avro.AvroRuntimeException;
+import org.apache.avro.AvroTypeException;
 import org.apache.avro.Conversion;
 import org.apache.avro.Conversions;
 import org.apache.avro.LogicalType;
@@ -257,7 +258,12 @@ public class GenericDatumReader<D> implements 
DatumReader<D> {
    */
   protected void readField(Object record, Field field, Object oldDatum, 
ResolvingDecoder in, Object state)
       throws IOException {
-    data.setField(record, field.name(), field.pos(), read(oldDatum, 
field.schema(), in), state);
+    try {
+      data.setField(record, field.name(), field.pos(), read(oldDatum, 
field.schema(), in), state);
+    } catch(AvroTypeException exception) {
+      String message = "Field \"" + field.name() + "\" content mismatch: " + 
exception.getMessage();
+      throw new AvroTypeException(message, exception.getCause());
+    }
   }
 
   /**
diff --git 
a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java
 
b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java
index ce701af12c..706f6bb985 100644
--- 
a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java
+++ 
b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibilityEnumDefaults.java
@@ -22,6 +22,7 @@ import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM2_AB_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM_ABC_ENUM_DEFAULT_A_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM_AB_ENUM_DEFAULT_A_SCHEMA;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
@@ -53,7 +54,7 @@ public class TestSchemaCompatibilityEnumDefaults {
     datum.put("field2", new GenericData.EnumSymbol(writerSchema, "B"));
     AvroTypeException avroTypeException = assertThrows(AvroTypeException.class,
         () -> serializeWithWriterThenDeserializeWithReader(writerSchema, 
datum, readerSchema));
-    assertEquals("Found Record1, expecting Record1, missing required field 
field1", avroTypeException.getMessage());
+    assertTrue(avroTypeException.getMessage().contains("Found Record1, 
expecting Record1, missing required field field1"));
   }
 
   @Test
@@ -111,7 +112,7 @@ public class TestSchemaCompatibilityEnumDefaults {
     datum.put("field1", new GenericData.EnumSymbol(writerSchema, "C"));
     AvroTypeException avroTypeException = assertThrows(AvroTypeException.class,
         () -> serializeWithWriterThenDeserializeWithReader(writerSchema, 
datum, readerSchema));
-    assertEquals("No match for C", avroTypeException.getMessage());
+    assertEquals("Field \"field1\" content mismatch: No match for C", 
avroTypeException.getMessage());
   }
 
   private GenericRecord serializeWithWriterThenDeserializeWithReader(Schema 
writerSchema, GenericRecord datum,
diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java 
b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
index 7f5e48fb96..9d398d635f 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
@@ -79,6 +79,6 @@ public class TestUnionError {
 
     GenericDatumReader<GenericRecord> datumReader = new 
GenericDatumReader<>(writerSchema, readerSchema);
     AvroTypeException avroException = assertThrows(AvroTypeException.class, () 
-> datumReader.read(null, decoder));
-    assertEquals("Found B, expecting union[A, float]", 
avroException.getMessage());
+    assertEquals("Field \"c\" content mismatch: Found B, expecting union[A, 
float]", avroException.getMessage());
   }
 }

Reply via email to