in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/HttpProtocolGeneratorUtils.java [94:152]
public static Set<StructureShape> generateErrorDispatcher(
GenerationContext context,
OperationShape operation,
Symbol responseType,
Consumer<GenerationContext> errorMessageCodeGenerator,
BiFunction<GenerationContext, OperationShape, Map<String, ShapeId>> operationErrorsToShapes,
DefaultBlockWriter defaultBlockWriter
) {
GoWriter writer = context.getWriter().get();
ServiceShape service = context.getService();
String protocolName = context.getProtocolName();
Set<StructureShape> errorShapes = new TreeSet<>();
String errorFunctionName = ProtocolGenerator.getOperationErrorDeserFunctionName(
operation, service, protocolName);
writer.addUseImports(SmithyGoDependency.SMITHY_MIDDLEWARE);
writer.openBlock("func $L(response $P, metadata *middleware.Metadata) error {", "}",
errorFunctionName, responseType, () -> {
writer.addUseImports(SmithyGoDependency.BYTES);
writer.addUseImports(SmithyGoDependency.IO);
// Copy the response body into a seekable type
writer.write("var errorBuffer bytes.Buffer");
writer.openBlock("if _, err := io.Copy(&errorBuffer, response.Body); err != nil {", "}", () -> {
writer.write("return &smithy.DeserializationError{Err: fmt.Errorf("
+ "\"failed to copy error response body, %w\", err)}");
});
writer.write("errorBody := bytes.NewReader(errorBuffer.Bytes())");
writer.write("");
// Set the default values for code and message.
writer.write("errorCode := \"UnknownError\"");
writer.write("errorMessage := errorCode");
writer.write("");
// Dispatch to the message/code generator to try to get the specific code and message.
errorMessageCodeGenerator.accept(context);
writer.openBlock("switch {", "}", () -> {
operationErrorsToShapes.apply(context, operation).forEach((name, errorId) -> {
StructureShape error = context.getModel().expectShape(errorId).asStructureShape().get();
errorShapes.add(error);
String errorDeserFunctionName = ProtocolGenerator.getErrorDeserFunctionName(
error, service, protocolName);
writer.addUseImports(SmithyGoDependency.STRINGS);
writer.openBlock("case strings.EqualFold($S, errorCode):", "", name, () -> {
writer.write("return $L(response, errorBody)", errorDeserFunctionName);
});
});
// Create a generic error
writer.addUseImports(SmithyGoDependency.SMITHY);
defaultBlockWriter.write(writer);
});
}).write("");
return errorShapes;
}