@AutoCodec: proper handling of checked exceptions thrown by constructors.
PiperOrigin-RevId: 180697983
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
index 8df0f87..7c7a1d1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
@@ -160,7 +161,7 @@
MethodSpec.Builder deserializeBuilder =
AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType);
buildDeserializeBody(deserializeBuilder, constructorParameters);
- addReturnNew(deserializeBuilder, encodedType, constructorParameters);
+ addReturnNew(deserializeBuilder, encodedType, constructor, constructorParameters);
codecClassBuilder.addMethod(deserializeBuilder.build());
}
@@ -289,11 +290,28 @@
* <p>Used by the {@link AutoCodec.Strategy.CONSTRUCTOR} strategy.
*/
private static void addReturnNew(
- MethodSpec.Builder builder, TypeElement type, List<? extends VariableElement> parameters) {
+ MethodSpec.Builder builder,
+ TypeElement type,
+ ExecutableElement constructor,
+ List<? extends VariableElement> parameters) {
+ List<? extends TypeMirror> allThrown = constructor.getThrownTypes();
+ if (!allThrown.isEmpty()) {
+ builder.beginControlFlow("try");
+ }
builder.addStatement(
"return new $T($L)",
TypeName.get(type.asType()),
parameters.stream().map(p -> p.getSimpleName() + "_").collect(Collectors.joining(", ")));
+ if (!allThrown.isEmpty()) {
+ for (TypeMirror thrown : allThrown) {
+ builder.nextControlFlow("catch ($T e)", TypeName.get(thrown));
+ builder.addStatement(
+ "throw new $T(\"$L constructor threw an exception\", e)",
+ SerializationException.class,
+ type.getQualifiedName());
+ }
+ builder.endControlFlow();
+ }
}
/**
@@ -399,7 +417,8 @@
NoSuchMethodException.class,
IllegalAccessException.class,
InvocationTargetException.class);
- builder.addStatement("throw new SerializationException(input.getClass().getName(), e)");
+ builder.addStatement(
+ "throw new $T(input.getClass().getName(), e)", SerializationException.class);
builder.endControlFlow();
builder.nextControlFlow("else");
builder.addStatement("codedOut.writeBoolNoTag(false)");
@@ -430,7 +449,7 @@
NoSuchMethodException.class,
IllegalAccessException.class,
InvocationTargetException.class);
- builder.addStatement("throw new SerializationException(className, e)");
+ builder.addStatement("throw new $T(className, e)", SerializationException.class);
builder.endControlFlow();
builder.endControlFlow();
builder.addStatement("return deserialized");