Skip to content

Commit

Permalink
AVRO-3993: [java] Add better exception msgs when writing invalid enum…
Browse files Browse the repository at this point in the history
… 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]>
  • Loading branch information
j256 and Gray Watson committed Jun 11, 2024
1 parent 4eaa27d commit 25651dc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lang/java/avro/src/main/java/org/apache/avro/Schema.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand Down Expand Up @@ -1113,7 +1114,12 @@ public boolean hasEnumSymbol(String symbol) {

@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
Expand Down
36 changes: 36 additions & 0 deletions lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
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;

Expand Down Expand Up @@ -636,4 +643,33 @@ void add_types() {
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));
}
}
}

0 comments on commit 25651dc

Please sign in to comment.