Skip to content

Commit cf12ba8

Browse files
author
Pritham Marupaka
committed
Don't create parameter records when there are no parameters for error
1 parent d045209 commit cf12ba8

File tree

14 files changed

+160
-138
lines changed

14 files changed

+160
-138
lines changed

conjure-java-core/src/integrationInput/java/com/palantir/another/EndpointSpecificErrors.java

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-java-core/src/integrationInput/java/com/palantir/product/EndpointSpecificTwoErrors.java

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-java-core/src/integrationInput/java/com/palantir/product/ErrorServiceAsync.java

+10-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-java-core/src/integrationInput/java/com/palantir/product/ErrorServiceBlocking.java

+10-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-java-core/src/main/java/com/palantir/conjure/java/Options.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,9 @@ default boolean excludeDialogueAsyncInterfaces() {
179179
}
180180

181181
/**
182-
* TODO(pm): flesh this out more. For errors associated with endpoints, this option enables the generated Dialogue
183-
* clients to return a result type.
182+
* If enabled, endpoints that have associated errors will return a result type: a sealed interface permitting
183+
* subclasses for the endpoint's return value, and each endpoint error. Each endpoint error is a subclass of
184+
* {@link com.palantir.conjure.java.lib.internal.ConjureErrors.BaseEndpointError}.
184185
*/
185186
@Value.Default
186187
default boolean generateDialogueEndpointErrorResultTypes() {

conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DefaultStaticFactoryMethodGenerator.java

+19-12
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,18 @@ private Optional<FieldSpec> deserializer(
181181
if (isBinaryOrOptionalBinary(className, returnTypes) && !options.generateDialogueEndpointErrorResultTypes()) {
182182
return Optional.empty();
183183
}
184-
ParameterizedTypeName deserializerType =
185-
ParameterizedTypeName.get(ClassName.get(Deserializer.class), responseType);
184+
185+
ParameterizedTypeName deserializerType;
186+
if (shouldGenerateDialogueEndpointErrorResultTypesForEndpoint(options, endpointDef)) {
187+
deserializerType = ParameterizedTypeName.get(ClassName.get(Deserializer.class), responseType);
188+
} else {
189+
deserializerType = ParameterizedTypeName.get(ClassName.get(Deserializer.class), className);
190+
}
186191

187192
CodeBlock initializer = CodeBlock.of(
188193
"$L.bodySerDe().$L",
189194
StaticFactoryMethodGenerator.RUNTIME,
190-
options.generateDialogueEndpointErrorResultTypes()
195+
shouldGenerateDialogueEndpointErrorResultTypesForEndpoint(options, endpointDef)
191196
? constructDeserializerWithEndpointErrors(endpointDef, className, responseType)
192197
: constructDeserializer(type, className));
193198

@@ -239,6 +244,12 @@ private static boolean isBinaryOrOptionalBinary(TypeName className, ReturnTypeMa
239244
return isBinary(className, returnTypes) || isOptionalBinary(className, returnTypes);
240245
}
241246

247+
private static boolean shouldGenerateDialogueEndpointErrorResultTypesForEndpoint(
248+
Options options, EndpointDefinition endpointDefinition) {
249+
return options.generateDialogueEndpointErrorResultTypes()
250+
&& !endpointDefinition.getErrors().isEmpty();
251+
}
252+
242253
private static boolean isBinary(TypeName className, ReturnTypeMapper returnTypes) {
243254
return className.equals(returnTypes.baseType(Type.primitive(PrimitiveType.BINARY)));
244255
}
@@ -280,13 +291,14 @@ private MethodSpec clientImpl(ClassName className, EndpointDefinition def) {
280291
.build();
281292
String codeBlock = methodType.switchBy(
282293
"$L.clients().callBlocking($L, $L.build(), $L);", "$L.clients().call($L, $L.build" + "(), $L);");
294+
boolean generateResultTypes = shouldGenerateDialogueEndpointErrorResultTypesForEndpoint(options, def);
283295
CodeBlock execute = CodeBlock.of(
284296
codeBlock,
285297
StaticFactoryMethodGenerator.RUNTIME,
286298
Names.endpointChannel(def),
287299
REQUEST,
288300
def.getReturns()
289-
.filter(type -> !options.generateDialogueEndpointErrorResultTypes()
301+
.filter(type -> !generateResultTypes
290302
&& isBinaryOrOptionalBinary(returnTypes.baseType(type), returnTypes))
291303
.map(type -> StaticFactoryMethodGenerator.RUNTIME
292304
+ (isOptionalBinary(returnTypes.baseType(type), returnTypes)
@@ -295,20 +307,15 @@ && isBinaryOrOptionalBinary(returnTypes.baseType(type), returnTypes))
295307
.orElseGet(() -> def.getEndpointName().get() + "Deserializer"));
296308

297309
methodBuilder.addCode(request);
298-
methodBuilder.addCode(methodType.switchBy(
299-
def.getReturns().isPresent()
300-
|| (options.generateDialogueEndpointErrorResultTypes()
301-
&& !def.getErrors().isEmpty())
302-
? "return "
303-
: "",
304-
"return "));
310+
methodBuilder.addCode(
311+
methodType.switchBy(def.getReturns().isPresent() || generateResultTypes ? "return " : "", "return "));
305312
methodBuilder.addCode(execute);
306313

307314
return methodBuilder.build();
308315
}
309316

310317
private TypeName getReturnType(EndpointDefinition def, ClassName className) {
311-
if (options.generateDialogueEndpointErrorResultTypes()
318+
if (shouldGenerateDialogueEndpointErrorResultTypesForEndpoint(options, def)
312319
&& !def.getErrors().isEmpty()) {
313320
ClassName returnType = ClassName.get(
314321
className.packageName(),

conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueInterfaceGenerator.java

+59-35
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,19 @@
2525
import com.google.errorprone.annotations.MustBeClosed;
2626
import com.palantir.conjure.java.ConjureAnnotations;
2727
import com.palantir.conjure.java.Options;
28+
import com.palantir.conjure.java.lib.internal.ConjureErrors;
2829
import com.palantir.conjure.java.lib.internal.ConjureErrors.BaseEndpointError;
2930
import com.palantir.conjure.java.services.IsUndertowAsyncMarkerVisitor;
3031
import com.palantir.conjure.java.services.ServiceGenerators;
3132
import com.palantir.conjure.java.services.ServiceGenerators.EndpointErrorsJavaDoc;
3233
import com.palantir.conjure.java.services.ServiceGenerators.EndpointJavaDocGenerationOptions;
3334
import com.palantir.conjure.java.services.ServiceGenerators.RequestLineJavaDoc;
3435
import com.palantir.conjure.java.util.ErrorGenerationUtils;
36+
import com.palantir.conjure.java.util.ErrorGenerationUtils.ErrorsAndParameters;
3537
import com.palantir.conjure.java.util.Packages;
3638
import com.palantir.conjure.spec.EndpointDefinition;
3739
import com.palantir.conjure.spec.EndpointError;
40+
import com.palantir.conjure.spec.ErrorTypeName;
3841
import com.palantir.conjure.spec.ServiceDefinition;
3942
import com.palantir.conjure.visitor.TypeVisitor;
4043
import com.palantir.dialogue.Channel;
@@ -66,12 +69,17 @@ public final class DialogueInterfaceGenerator {
6669
private final Options options;
6770
private final ParameterTypeMapper parameterTypes;
6871
private final ReturnTypeMapper returnTypes;
72+
private final ErrorsAndParameters errorsAndParameters;
6973

7074
public DialogueInterfaceGenerator(
71-
Options options, ParameterTypeMapper parameterTypes, ReturnTypeMapper returnTypes) {
75+
Options options,
76+
ParameterTypeMapper parameterTypes,
77+
ReturnTypeMapper returnTypes,
78+
ErrorsAndParameters errorsAndParameters) {
7279
this.options = options;
7380
this.parameterTypes = parameterTypes;
7481
this.returnTypes = returnTypes;
82+
this.errorsAndParameters = errorsAndParameters;
7583
}
7684

7785
public JavaFile generateBlocking(
@@ -190,29 +198,7 @@ private TypeSpec responseTypeForEndpoint(String packageName, ClassName className
190198
// Create a record for each of the endpoint's errors
191199
List<TypeSpec> errorTypes = new ArrayList<>();
192200
for (EndpointError endpointError : endpointDef.getErrors()) {
193-
String errorTypeName = CaseFormat.UPPER_CAMEL.to(
194-
CaseFormat.UPPER_UNDERSCORE, endpointError.getError().getName());
195-
ClassName errorTypesClassName = ClassName.get(
196-
endpointError.getError().getPackage(),
197-
ErrorGenerationUtils.errorTypesClassName(
198-
endpointError.getError().getNamespace()),
199-
errorTypeName);
200-
ClassName parametersClassName = ClassName.get(
201-
endpointError.getError().getPackage(),
202-
ErrorGenerationUtils.errorTypesClassName(
203-
endpointError.getError().getNamespace()),
204-
ErrorGenerationUtils.errorParametersClassName(
205-
endpointError.getError().getName()));
206-
TypeSpec endpointErrorType = TypeSpec.classBuilder(ClassName.get(
207-
packageName,
208-
responseTypeName.simpleName(),
209-
endpointError.getError().getName()))
210-
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
211-
.addSuperinterface(responseTypeName)
212-
.superclass(ParameterizedTypeName.get(ClassName.get(BaseEndpointError.class), parametersClassName))
213-
.addMethod(errorTypeConstructor(parametersClassName, errorTypesClassName))
214-
.build();
215-
errorTypes.add(endpointErrorType);
201+
errorTypes.add(constructEndpointErrorType(endpointError, packageName, responseTypeName));
216202
}
217203

218204
// Get type from typespec
@@ -229,6 +215,39 @@ private TypeSpec responseTypeForEndpoint(String packageName, ClassName className
229215
.build();
230216
}
231217

218+
private TypeSpec constructEndpointErrorType(
219+
EndpointError endpointError, String packageName, ClassName responseTypeName) {
220+
String errorTypeName = CaseFormat.UPPER_CAMEL.to(
221+
CaseFormat.UPPER_UNDERSCORE, endpointError.getError().getName());
222+
ClassName errorTypesClassName = ClassName.get(
223+
endpointError.getError().getPackage(),
224+
ErrorGenerationUtils.errorTypesClassName(
225+
endpointError.getError().getNamespace()),
226+
errorTypeName);
227+
228+
TypeSpec.Builder endpointErrorTypeBuilder = TypeSpec.classBuilder(ClassName.get(
229+
packageName,
230+
responseTypeName.simpleName(),
231+
endpointError.getError().getName()))
232+
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
233+
.addSuperinterface(responseTypeName);
234+
ClassName parametersClassName;
235+
if (errorsAndParameters.hasParameters(endpointError.getError())) {
236+
parametersClassName = ClassName.get(
237+
endpointError.getError().getPackage(),
238+
ErrorGenerationUtils.errorTypesClassName(
239+
endpointError.getError().getNamespace()),
240+
ErrorGenerationUtils.errorParametersClassName(
241+
endpointError.getError().getName()));
242+
} else {
243+
parametersClassName = ClassName.get(ConjureErrors.EmptyErrorParameters.class);
244+
}
245+
endpointErrorTypeBuilder
246+
.superclass(ParameterizedTypeName.get(ClassName.get(BaseEndpointError.class), parametersClassName))
247+
.addMethod(errorTypeConstructor(endpointError.getError(), parametersClassName, errorTypesClassName));
248+
return endpointErrorTypeBuilder.build();
249+
}
250+
232251
private TypeSpec createSuccessRecord(
233252
String packageName, ClassName className, ClassName responseTypeName, EndpointDefinition endpointDef) {
234253
ClassName successTypeClassName =
@@ -263,7 +282,8 @@ private TypeSpec createSuccessRecord(
263282
return successRecordBuilder.build();
264283
}
265284

266-
private MethodSpec errorTypeConstructor(ClassName parametersClassName, ClassName errorTypesClassName) {
285+
private MethodSpec errorTypeConstructor(
286+
ErrorTypeName errorTypeName, ClassName parametersClassName, ClassName errorTypesClassName) {
267287
MethodSpec.Builder ctorBuilder = MethodSpec.constructorBuilder()
268288
.addAnnotation(JsonCreator.class)
269289
.addParameter(ParameterSpec.builder(ClassName.get(String.class), "errorCode")
@@ -275,16 +295,20 @@ private MethodSpec errorTypeConstructor(ClassName parametersClassName, ClassName
275295
.addAnnotation(AnnotationSpec.builder(JsonProperty.class)
276296
.addMember("value", "$S", "errorInstanceId")
277297
.build())
278-
.build())
279-
// TODO(pm): Only add the parameters if the error has them. Plumb in error definitions.
280-
.addParameter(ParameterSpec.builder(parametersClassName, "parameters")
281-
.addAnnotation(AnnotationSpec.builder(JsonProperty.class)
282-
.addMember("value", "$S", "parameters")
283-
.build())
284-
.build())
285-
.addStatement(
286-
// TODO(pm): Perhaps these shouldn't be literals but names ($N).
287-
"super(errorCode, $T.name(), errorInstanceId, parameters)", errorTypesClassName);
298+
.build());
299+
if (errorsAndParameters.hasParameters(errorTypeName)) {
300+
ctorBuilder.addParameter(ParameterSpec.builder(parametersClassName, "parameters")
301+
.addAnnotation(AnnotationSpec.builder(JsonProperty.class)
302+
.addMember("value", "$S", "parameters")
303+
.build())
304+
.build());
305+
ctorBuilder.addStatement("super(errorCode, $T.name(), errorInstanceId, parameters)", errorTypesClassName);
306+
} else {
307+
ctorBuilder.addStatement(
308+
"super(errorCode, $T.name(), errorInstanceId, $T.EMPTY_ERROR_PARAMETERS_INSTANCE)",
309+
errorTypesClassName,
310+
ClassName.get(ConjureErrors.class));
311+
}
288312
return ctorBuilder.build();
289313
}
290314

conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueServiceGenerator.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.palantir.conjure.java.types.SafetyEvaluator;
2323
import com.palantir.conjure.java.types.SpecializeBinaryClassNameVisitor;
2424
import com.palantir.conjure.java.types.TypeMapper;
25+
import com.palantir.conjure.java.util.ErrorGenerationUtils.ErrorsAndParameters;
2526
import com.palantir.conjure.java.util.TypeFunctions;
2627
import com.palantir.conjure.spec.ConjureDefinition;
2728
import com.palantir.conjure.spec.ServiceDefinition;
@@ -64,8 +65,9 @@ public Stream<JavaFile> generate(ConjureDefinition conjureDefinition) {
6465
new DefaultClassNameVisitor(types.keySet(), options), types, ClassName.get(InputStream.class)));
6566
ParameterTypeMapper parameterMapper = new ParameterTypeMapper(parameterTypes, safetyEvaluator);
6667

67-
DialogueInterfaceGenerator interfaceGenerator =
68-
new DialogueInterfaceGenerator(options, parameterMapper, new ReturnTypeMapper(returnTypes));
68+
ErrorsAndParameters errorsAndParameters = ErrorsAndParameters.from(conjureDefinition);
69+
DialogueInterfaceGenerator interfaceGenerator = new DialogueInterfaceGenerator(
70+
options, parameterMapper, new ReturnTypeMapper(returnTypes), errorsAndParameters);
6971

7072
TypeNameResolver typeNameResolver = typeName -> Preconditions.checkNotNull(
7173
types.get(typeName), "Referenced unknown TypeName", SafeArg.of("typeName", typeName));

0 commit comments

Comments
 (0)