From 76cd590ca30e09bd9353b5e2900c4be112cd146a Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Mon, 10 Sep 2018 20:41:38 -0400 Subject: [PATCH] Generate nicer stacktraces when creating a generated adapter fails. Otherwise we end up with many InvocationTargetExceptions layered in, which makes it difficult to identify what actually failed. --- moshi/src/main/java/com/squareup/moshi/ClassFactory.java | 3 ++- .../main/java/com/squareup/moshi/ClassJsonAdapter.java | 5 +---- .../java/com/squareup/moshi/StandardJsonAdapters.java | 5 ++--- .../src/main/java/com/squareup/moshi/internal/Util.java | 9 +++++++++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/moshi/src/main/java/com/squareup/moshi/ClassFactory.java b/moshi/src/main/java/com/squareup/moshi/ClassFactory.java index 48a4212..b332039 100644 --- a/moshi/src/main/java/com/squareup/moshi/ClassFactory.java +++ b/moshi/src/main/java/com/squareup/moshi/ClassFactory.java @@ -15,6 +15,7 @@ */ package com.squareup.moshi; +import com.squareup.moshi.internal.Util; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.lang.reflect.Constructor; @@ -103,7 +104,7 @@ abstract class ClassFactory { } catch (IllegalAccessException e) { throw new AssertionError(); } catch (InvocationTargetException e) { - throw new RuntimeException(e); + throw Util.rethrowCause(e); } catch (NoSuchMethodException ignored) { // Not the expected version of Dalvik/libcore! } diff --git a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java index 5517de5..aee6d55 100644 --- a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java +++ b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java @@ -138,10 +138,7 @@ final class ClassJsonAdapter extends JsonAdapter { } catch (InstantiationException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { - Throwable targetException = e.getTargetException(); - if (targetException instanceof RuntimeException) throw (RuntimeException) targetException; - if (targetException instanceof Error) throw (Error) targetException; - throw new RuntimeException(targetException); + throw Util.rethrowCause(e); } catch (IllegalAccessException e) { throw new AssertionError(); } diff --git a/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java b/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java index 5c94c89..5513736 100644 --- a/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java +++ b/moshi/src/main/java/com/squareup/moshi/StandardJsonAdapters.java @@ -254,12 +254,11 @@ final class StandardJsonAdapters { } catch (IllegalAccessException e) { throw new RuntimeException( "Failed to access the generated JsonAdapter for " + rawType, e); - } catch (InvocationTargetException e) { - throw new RuntimeException( - "Failed to construct the generated JsonAdapter for " + rawType, e); } catch (InstantiationException e) { throw new RuntimeException( "Failed to instantiate the generated JsonAdapter for " + rawType, e); + } catch (InvocationTargetException e) { + throw Util.rethrowCause(e); } } diff --git a/moshi/src/main/java/com/squareup/moshi/internal/Util.java b/moshi/src/main/java/com/squareup/moshi/internal/Util.java index 1bd0c9a..832ac2f 100644 --- a/moshi/src/main/java/com/squareup/moshi/internal/Util.java +++ b/moshi/src/main/java/com/squareup/moshi/internal/Util.java @@ -21,6 +21,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -95,6 +96,14 @@ public final class Util { || name.startsWith("scala."); } + /** Throws the cause of {@code e}, wrapping it if it is checked. */ + public static RuntimeException rethrowCause(InvocationTargetException e) { + Throwable cause = e.getTargetException(); + if (cause instanceof RuntimeException) throw (RuntimeException) cause; + if (cause instanceof Error) throw (Error) cause; + throw new RuntimeException(cause); + } + /** * Returns a type that is functionally equal but not necessarily equal according to {@link * Object#equals(Object) Object.equals()}.