Skip to content

Commit b065cf5

Browse files
committed
use HttpResponseException
1 parent 243495f commit b065cf5

File tree

4 files changed

+100
-55
lines changed

4 files changed

+100
-55
lines changed

sdk/clientcore/annotation-processor-test/src/test/java/io/clientcore/annotation/processor/test/TestInterfaceServiceClientGenerationTests.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,6 @@ public void putRequestWithBodyAndEqualContentLength() {
10421042
}
10431043

10441044
@Test
1045-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
10461045
public void putRequestWithBodyLessThanContentLength() {
10471046
ByteBuffer body = ByteBuffer.wrap("test".getBytes(StandardCharsets.UTF_8));
10481047
Exception unexpectedLengthException = assertThrows(Exception.class, () -> {
@@ -1068,7 +1067,6 @@ public void putRequestWithBodyMoreThanContentLength() {
10681067
}
10691068

10701069
@Test
1071-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
10721070
public void putRequestWithUnexpectedResponseAndNoFallthroughExceptionType() {
10731071
HttpResponseException e = assertThrows(HttpResponseException.class,
10741072
() -> createService(TestInterfaceClientImpl.TestInterfaceClientService.class)
@@ -1204,7 +1202,6 @@ public void service18GetStatus300WithExpectedResponse300() {
12041202
}
12051203

12061204
@Test
1207-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
12081205
public void service18GetStatus400() {
12091206
assertThrows(HttpResponseException.class,
12101207
() -> createService(TestInterfaceClientImpl.TestInterfaceClientService.class)
@@ -1218,7 +1215,6 @@ public void service18GetStatus400WithExpectedResponse400() {
12181215
}
12191216

12201217
@Test
1221-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
12221218
public void service18GetStatus500() {
12231219
assertThrows(HttpResponseException.class,
12241220
() -> createService(TestInterfaceClientImpl.TestInterfaceClientService.class)
@@ -1290,7 +1286,6 @@ public void service20GetResponseBody() {
12901286
}
12911287

12921288
@Test
1293-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
12941289
public void unexpectedHTTPOK() {
12951290
HttpResponseException e = assertThrows(HttpResponseException.class,
12961291
() -> createService(TestInterfaceClientImpl.TestInterfaceClientService.class).getBytes(getRequestUri()));
@@ -1449,7 +1444,6 @@ public void voidDoesNotEagerlyReadResponse(
14491444

14501445
@ParameterizedTest
14511446
@MethodSource("voidErrorReturnsErrorBodySupplier")
1452-
@Disabled("https://github.com/Azure/azure-sdk-for-java/issues/43728")
14531447
public void
14541448
voidErrorReturnsErrorBody(BiConsumer<String, TestInterfaceClientImpl.TestInterfaceClientService> executable) {
14551449
HttpResponseException exception = assertThrows(HttpResponseException.class, () -> executable

sdk/clientcore/annotation-processor/src/main/java/io/clientcore/annotation/processor/AnnotationProcessor.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ private void processServiceInterface(Element serviceInterface) {
121121
.map(e -> e.getAnnotation(UnexpectedResponseExceptionDetail.class))
122122
.filter(Objects::nonNull) // Exclude null annotations
123123
.collect(Collectors.toList()));
124-
125124
// Process the template
126125
TemplateProcessor.getInstance().process(templateInput, processingEnv);
127126

sdk/clientcore/annotation-processor/src/main/java/io/clientcore/annotation/processor/templating/JavaParserTemplateProcessor.java

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.clientcore.core.http.models.HttpHeaderName;
2929
import io.clientcore.core.http.models.HttpMethod;
3030
import io.clientcore.core.http.models.HttpRequest;
31+
import io.clientcore.core.http.models.HttpResponseException;
3132
import io.clientcore.core.http.models.Response;
3233
import io.clientcore.core.http.pipeline.HttpPipeline;
3334
import io.clientcore.core.implementation.utils.UriEscapers;
@@ -38,6 +39,7 @@
3839
import java.io.IOException;
3940
import java.io.Writer;
4041
import java.lang.reflect.Field;
42+
import java.nio.charset.StandardCharsets;
4143
import java.util.Arrays;
4244
import java.util.HashMap;
4345
import java.util.LinkedHashMap;
@@ -47,6 +49,8 @@
4749
import java.util.Optional;
4850
import java.util.stream.Collectors;
4951
import javax.annotation.processing.ProcessingEnvironment;
52+
import javax.lang.model.element.TypeElement;
53+
import javax.lang.model.type.DeclaredType;
5054
import javax.lang.model.type.TypeKind;
5155
import javax.lang.model.type.TypeMirror;
5256

@@ -141,6 +145,34 @@ void createClass(String serviceInterfaceImplShortName, String serviceInterfaceSh
141145
processingEnv);
142146
}
143147
}
148+
149+
addInstantiateExceptionHelperMethod(classBuilder.addMethod("instantiateUnexpectedException",
150+
Modifier.Keyword.PRIVATE, Modifier.Keyword.STATIC));
151+
}
152+
153+
private void addInstantiateExceptionHelperMethod(MethodDeclaration instantiateUnexpectedException) {
154+
instantiateUnexpectedException.setType("HttpResponseException")
155+
.addParameter("int", "responseCode")
156+
.addParameter("Response<BinaryData>", "response")
157+
.addParameter("BinaryData", "data")
158+
.addParameter("Object", "decodedValue");
159+
instantiateUnexpectedException.setBody(StaticJavaParser.parseBlock("{\n"
160+
+ " StringBuilder exceptionMessage = new StringBuilder(\"Status code \")\n"
161+
+ " .append(responseCode).append(\", \");\n"
162+
+ " String contentType = response.getHeaders().getValue(HttpHeaderName.CONTENT_TYPE);\n"
163+
+ " if (\"application/octet-stream\".equalsIgnoreCase(contentType)) {\n"
164+
+ " String contentLength = response.getHeaders().getValue(HttpHeaderName.CONTENT_LENGTH);\n"
165+
+ " exceptionMessage.append(\"(\").append(contentLength).append(\"-byte body)\");\n"
166+
+ " } else if (data == null || data.toBytes().length == 0) {\n"
167+
+ " exceptionMessage.append(\"(empty body)\");\n" + " } else {\n"
168+
+ " exceptionMessage.append('\"').append(new String(data.toBytes(), StandardCharsets.UTF_8)).append('\"');\n"
169+
+ " }\n"
170+
+ " if (decodedValue instanceof IOException || decodedValue instanceof IllegalStateException) {\n"
171+
+ " return new HttpResponseException(exceptionMessage.toString(), response, (Throwable) decodedValue);\n"
172+
+ " }\n" + " return new HttpResponseException(exceptionMessage.toString(), response, decodedValue);\n"
173+
+ "}"));
174+
instantiateUnexpectedException.tryAddImportToParentCompilationUnit(HttpResponseException.class);
175+
instantiateUnexpectedException.tryAddImportToParentCompilationUnit(StandardCharsets.class);
144176
}
145177

146178
private void addLoggerField(String serviceInterfaceShortName) {
@@ -402,17 +434,14 @@ private void appendQueryParams(BlockStmt body, HttpRequestContext method) {
402434
}
403435

404436
/**
405-
* Adds headers to the HttpRequest using the provided HttpRequestContext.
406-
* Handles both static and dynamic headers, and applies correct quoting logic for static values.
437+
* Adds headers to the HttpRequest using the provided HttpRequestContext. Handles both static and dynamic headers,
438+
* and applies correct quoting logic for static values.
407439
* <p>
408-
* Quoting logic:
409-
* - If value starts and ends with ", use as-is.
410-
* - If starts with ", append trailing ".
411-
* - If ends with ", prepend leading ".
412-
* - Otherwise, wrap value in quotes.
440+
* Quoting logic: - If value starts and ends with ", use as-is. - If starts with ", append trailing ". - If ends
441+
* with ", prepend leading ". - Otherwise, wrap value in quotes.
413442
* <p>
414-
* For dynamic headers (parameter-based), values are not quoted.
415-
* For static headers (literal values), quoting is always applied.
443+
* For dynamic headers (parameter-based), values are not quoted. For static headers (literal values), quoting is
444+
* always applied.
416445
* <p>
417446
*/
418447
private void addHeadersToRequest(BlockStmt body, HttpRequestContext method) {
@@ -506,21 +535,17 @@ private void finalizeHttpRequest(BlockStmt body, TypeMirror returnTypeName, Http
506535
statement.setLineComment("\n Send the request through the httpPipeline");
507536
body.addStatement(statement);
508537

509-
if (!method.getExpectedStatusCodes().isEmpty()) {
510-
validateResponseStatus(body, method);
511-
}
538+
validateResponseStatus(body, method);
512539

513540
generateResponseHandling(body, returnTypeName, method, serializationFormatSet);
514541
}
515542

516543
private void validateResponseStatus(BlockStmt body, HttpRequestContext method) {
517-
if (method.getExpectedStatusCodes().isEmpty()) {
518-
return;
519-
}
520-
521544
body.addStatement(StaticJavaParser.parseStatement("int responseCode = networkResponse.getStatusCode();"));
522545
String expectedResponseCheck;
523-
if (method.getExpectedStatusCodes().size() == 1) {
546+
if (CoreUtils.isNullOrEmpty(method.getExpectedStatusCodes())) {
547+
expectedResponseCheck = "responseCode < 400;";
548+
} else if (method.getExpectedStatusCodes().size() == 1) {
524549
expectedResponseCheck = "responseCode == " + method.getExpectedStatusCodes().get(0) + ";";
525550
} else {
526551
String statusCodes = method.getExpectedStatusCodes()
@@ -530,9 +555,64 @@ private void validateResponseStatus(BlockStmt body, HttpRequestContext method) {
530555
expectedResponseCheck = "(" + statusCodes + ");";
531556
}
532557
body.addStatement(StaticJavaParser.parseStatement("boolean expectedResponse = " + expectedResponseCheck));
558+
// Generate the error handling block with dynamic ParameterizedType creation
559+
StringBuilder errorBlock = new StringBuilder();
560+
errorBlock.append("if (!expectedResponse) {\n")
561+
.append(
562+
" if (networkResponse.getValue() == null || networkResponse.getValue().toBytes().length == 0) {\n")
563+
.append(" throw instantiateUnexpectedException(responseCode, networkResponse, null, null);\n")
564+
.append(" } else {\n");
565+
566+
// Dynamically generate ParameterizedType if return type is declared
567+
TypeMirror returnType = method.getMethodReturnType();
568+
if (returnType.getKind() == TypeKind.DECLARED) {
569+
DeclaredType declaredType = (DeclaredType) returnType;
570+
TypeElement typeElement = (TypeElement) declaredType.asElement();
571+
body.tryAddImportToParentCompilationUnit(CoreUtils.class);
572+
StringBuilder paramTypeBuilder = new StringBuilder();
573+
paramTypeBuilder.append(typeElement.getQualifiedName().toString()).append(".class");
574+
575+
if (!declaredType.getTypeArguments().isEmpty()) {
576+
TypeMirror firstGenericType = declaredType.getTypeArguments().get(0);
577+
578+
if (firstGenericType instanceof DeclaredType) {
579+
DeclaredType genericDeclaredType = (DeclaredType) firstGenericType;
580+
TypeElement genericTypeElement = (TypeElement) genericDeclaredType.asElement();
581+
582+
body.findCompilationUnit()
583+
.ifPresent(compilationUnit -> compilationUnit
584+
.addImport(genericTypeElement.getQualifiedName().toString()));
585+
586+
if (genericTypeElement.getQualifiedName().contentEquals(List.class.getCanonicalName())) {
587+
if (!genericDeclaredType.getTypeArguments().isEmpty()) {
588+
String innerType
589+
= ((DeclaredType) genericDeclaredType.getTypeArguments().get(0)).asElement()
590+
.getSimpleName()
591+
.toString();
592+
paramTypeBuilder.append(", ").append(innerType).append(".class");
593+
}
594+
} else {
595+
String genericType = ((DeclaredType) declaredType.getTypeArguments().get(0)).asElement()
596+
.getSimpleName()
597+
.toString();
598+
paramTypeBuilder.append(", ").append(genericType).append(".class");
599+
600+
}
601+
}
602+
}
603+
errorBlock.append(" ParameterizedType returnType = CoreUtils.createParameterizedType(")
604+
.append(paramTypeBuilder)
605+
.append(");\n");
606+
} else {
607+
errorBlock.append(" ParameterizedType returnType = null;\n");
608+
609+
}
533610

534-
body.tryAddImportToParentCompilationUnit(RuntimeException.class);
535-
body.addStatement(StaticJavaParser.parseStatement("if (!expectedResponse) {"
536-
+ " throw new RuntimeException(\"Unexpected response code: \" + responseCode); }"));
611+
errorBlock.append(
612+
" throw instantiateUnexpectedException(responseCode, networkResponse, networkResponse.getValue(), ")
613+
.append("decodeNetworkResponse(networkResponse.getValue(), jsonSerializer, returnType));\n")
614+
.append(" }\n")
615+
.append("}\n");
616+
body.addStatement(StaticJavaParser.parseStatement(errorBlock.toString()));
537617
}
538618
}

sdk/clientcore/core/src/main/java/io/clientcore/core/implementation/http/serializer/MalformedValueException.java

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)