Author: cutting
Date: Wed Nov 11 22:04:05 2009
New Revision: 835094

URL: http://svn.apache.org/viewvc?rev=835094&view=rev
Log:
AVRO-192.  Improved errors for Java schema parsing problems.

Modified:
    hadoop/avro/trunk/CHANGES.txt
    hadoop/avro/trunk/src/java/org/apache/avro/Schema.java
    hadoop/avro/trunk/src/test/java/org/apache/avro/TestSchema.java

Modified: hadoop/avro/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=835094&r1=835093&r2=835094&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Wed Nov 11 22:04:05 2009
@@ -54,6 +54,8 @@
 
     AVRO-188. Need to update svn ignores (massie)
 
+    AVRO-192. Improved errors for Java schema parsing problems. (cutting)
+
   OPTIMIZATIONS
 
     AVRO-172. More efficient schema processing (massie)

Modified: hadoop/avro/trunk/src/java/org/apache/avro/Schema.java
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/Schema.java?rev=835094&r1=835093&r2=835094&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/Schema.java (original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/Schema.java Wed Nov 11 22:04:05 
2009
@@ -746,9 +746,15 @@
         if (name != null) names.add(result);
         return result;
       } else if (type.equals("array")) {          // array
-        return new ArraySchema(parse(schema.get("items"), names));
+        JsonNode itemsNode = schema.get("items");
+        if (itemsNode == null)
+          throw new SchemaParseException("Array has no items type: "+schema);
+        return new ArraySchema(parse(itemsNode, names));
       } else if (type.equals("map")) {            // map
-        return new MapSchema(parse(schema.get("values"), names));
+        JsonNode valuesNode = schema.get("values");
+        if (valuesNode == null)
+          throw new SchemaParseException("Map has no values type: "+schema);
+        return new MapSchema(parse(valuesNode, names));
       } else if (type.equals("fixed")) {          // fixed
         JsonNode sizeNode = schema.get("size");
         if (sizeNode == null || !sizeNode.isInt())

Modified: hadoop/avro/trunk/src/test/java/org/apache/avro/TestSchema.java
URL: 
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/java/org/apache/avro/TestSchema.java?rev=835094&r1=835093&r2=835094&view=diff
==============================================================================
--- hadoop/avro/trunk/src/test/java/org/apache/avro/TestSchema.java (original)
+++ hadoop/avro/trunk/src/test/java/org/apache/avro/TestSchema.java Wed Nov 11 
22:04:05 2009
@@ -20,6 +20,7 @@
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -98,6 +99,7 @@
     GenericArray<Long> array = new GenericData.Array<Long>(1, schema);
     array.add(1L);
     check(json, "[1]", array);
+    checkParseError("{\"type\":\"array\"}");      // items required
   }
 
   @Test
@@ -105,6 +107,7 @@
     HashMap<Utf8,Long> map = new HashMap<Utf8,Long>();
     map.put(new Utf8("a"), 1L);
     check("{\"type\":\"map\", \"values\":\"long\"}", "{\"a\":1}", map);
+    checkParseError("{\"type\":\"map\"}");        // values required
   }
 
   @Test
@@ -115,17 +118,26 @@
     GenericData.Record record = new GenericData.Record(schema);
     record.put("f", 11L);
     check(recordJson, "{\"f\":11}", record, false);
+    checkParseError("{\"type\":\"record\"}");
+    checkParseError("{\"type\":\"record\",\"name\":\"X\"}");
+    checkParseError("{\"type\":\"record\",\"name\":\"X\",\"fields\":\"Y\"}");
+    checkParseError("{\"type\":\"record\",\"name\":\"X\",\"fields\":"
+                    +"[{\"name\":\"f\"}]}");       // no type
+    checkParseError("{\"type\":\"record\",\"name\":\"X\",\"fields\":"
+                    +"[{\"type\":\"long\"}]}");    // no name
   }
 
   @Test
   public void testEnum() throws Exception {
     check(BASIC_ENUM_SCHEMA, "\"B\"", "B", false);
+    checkParseError("{\"type\":\"enum\"}");        // symbols required
   }
 
   @Test
   public void testFixed() throws Exception {
     check("{\"type\": \"fixed\", \"name\":\"Test\", \"size\": 1}", "\"a\"",
           new GenericData.Fixed(new byte[]{(byte)'a'}), false);
+    checkParseError("{\"type\":\"fixed\"}");        // size required
   }
 
   @Test
@@ -179,6 +191,15 @@
     checkJson(union, "X", "{\"Baz\":\"X\"}");
   }
 
+  private static void checkParseError(String json) {
+    try {
+      Schema schema = Schema.parse(json);
+    } catch (SchemaParseException e) {
+      return;
+    }
+    fail("Should not have parsed: "+json);
+  }
+
   private static void check(String schemaJson, String defaultJson,
                             Object defaultValue) throws Exception {
     check(schemaJson, defaultJson, defaultValue, true);


Reply via email to