diff --git a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java index 97bbb89..6a3ec9c 100644 --- a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java +++ b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java @@ -39,9 +39,18 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { final AdapterMethod fromAdapter = get(fromAdapters, type, annotations); if (toAdapter == null && fromAdapter == null) return null; - final JsonAdapter delegate = toAdapter == null || fromAdapter == null - ? moshi.nextAdapter(this, type, annotations) - : null; + final JsonAdapter delegate; + if (toAdapter == null || fromAdapter == null) { + try { + delegate = moshi.nextAdapter(this, type, annotations); + } catch (IllegalArgumentException e) { + String missingAnnotation = toAdapter == null ? "@ToJson" : "@FromJson"; + throw new IllegalArgumentException("No " + missingAnnotation + " adapter for " + + type + " annotated " + annotations); + } + } else { + delegate = null; + } return new JsonAdapter() { @Override public void toJson(JsonWriter writer, Object value) throws IOException { diff --git a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java index 2de853b..a0d32c5 100644 --- a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java +++ b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java @@ -264,6 +264,44 @@ public final class AdapterMethodsTest { } } + @Test public void adapterDoesToJsonOnly() throws Exception { + Object shapeToJsonAdapter = new Object() { + @ToJson String shapeToJson(Shape shape) { + throw new AssertionError(); + } + }; + + Moshi toJsonMoshi = new Moshi.Builder() + .add(shapeToJsonAdapter) + .build(); + try { + toJsonMoshi.adapter(Shape.class); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("No @FromJson adapter for interface " + + "com.squareup.moshi.AdapterMethodsTest$Shape annotated []"); + } + } + + @Test public void adapterDoesFromJsonOnly() throws Exception { + Object shapeFromJsonAdapter = new Object() { + @FromJson Shape shapeFromJson(String shape) { + throw new AssertionError(); + } + }; + + Moshi fromJsonMoshi = new Moshi.Builder() + .add(shapeFromJsonAdapter) + .build(); + try { + fromJsonMoshi.adapter(Shape.class); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("No @ToJson adapter for interface " + + "com.squareup.moshi.AdapterMethodsTest$Shape annotated []"); + } + } + static class Point { final int x; final int y; @@ -281,4 +319,8 @@ public final class AdapterMethodsTest { return x * 37 + y; } } + + interface Shape { + String draw(); + } } diff --git a/moshi/src/test/java/com/squareup/moshi/JsonQualifiersTest.java b/moshi/src/test/java/com/squareup/moshi/JsonQualifiersTest.java index 416afa2..0dfe77e 100644 --- a/moshi/src/test/java/com/squareup/moshi/JsonQualifiersTest.java +++ b/moshi/src/test/java/com/squareup/moshi/JsonQualifiersTest.java @@ -332,7 +332,7 @@ public final class JsonQualifiersTest { moshi.adapter(StringAndFooString.class); fail(); } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("No JsonAdapter for class java.lang.String " + assertThat(expected).hasMessage("No @FromJson adapter for class java.lang.String " + "annotated [@com.squareup.moshi.JsonQualifiersTest$FooPrefix()]"); } } @@ -353,7 +353,7 @@ public final class JsonQualifiersTest { moshi.adapter(StringAndFooString.class); fail(); } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("No JsonAdapter for class java.lang.String " + assertThat(expected).hasMessage("No @ToJson adapter for class java.lang.String " + "annotated [@com.squareup.moshi.JsonQualifiersTest$FooPrefix()]"); } }