Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for BatchError.fromExeception #44538

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions sdk/batch/azure-compute-batch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ BatchTaskCreateContent taskToCreate = new BatchTaskCreateContent(taskId, "echo h
batchClient.createTask(jobId, taskToCreate);
```

Error handling

When a call to the batch service fails the response from that call will contain a BatchError object in the body of the response. In the AZURE-COMPUTE-BATCH SDK when an api method is called and a failure from the server occurs the sdk will throw a HttpResponseException exception. You can use the helper method BatchError.fromException() to extract out the BatchError object.

```java
try(

BatchPool pool = batchClient.getPool("poolthatdoesnotexist");

} catch (HttpResponseException err) {

BatchError batchError = BatchError.fromException(err);
Assertions.assertEquals("PoolNotFound", error.getCode());
}
```

## Help

If you encounter any bugs with these libraries, please file issues via [Issues](https://github.com/Azure/azure-sdk-for-java) or check out [StackOverflow for Azure Java SDK](https://stackoverflow.com/questions/tagged/azure-java-sdk).
Expand Down
2 changes: 1 addition & 1 deletion sdk/batch/azure-compute-batch/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "java",
"TagPrefix": "java/batch/azure-compute-batch",
"Tag": "java/batch/azure-compute-batch_ead064573c"
"Tag": "java/batch/azure-compute-batch_36edb7c93c"
}
6 changes: 6 additions & 0 deletions sdk/batch/azure-compute-batch/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,11 @@
<version>12.29.0</version> <!-- {x-version-update;com.azure:azure-storage-blob;dependency} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version> <!-- {x-version-update;org.mockito:mockito-core;external_dependency} -->
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@

import com.azure.core.annotation.Generated;
import com.azure.core.annotation.Immutable;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.HttpResponse;
import com.azure.json.JsonProviders;
import com.azure.json.JsonReader;
import com.azure.json.JsonSerializable;
import com.azure.json.JsonToken;
import com.azure.json.JsonWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

/**
Expand Down Expand Up @@ -125,4 +129,35 @@ public static BatchError fromJson(JsonReader jsonReader) throws IOException {
return deserializedBatchError;
});
}

/**
* Reads an instance of BatchError from an HttpResponseException.
*
* @param err The HttpResponseException based exception returned from an api
* call.
* @return An instance of BatchError if the HttpResponseException containted an
* instance of it, or null if it was pointing
* to an HttpResponseException with no BatchError.
*/
public static BatchError fromException(HttpResponseException err) {
if (err == null) {
return null;
}
HttpResponse response = err.getResponse();
if (response == null) {
return null;
}
String bodyastring = response.getBodyAsString().block();
if (bodyastring == null) {
return null;
}
JsonReader jsonReader;
try {
jsonReader = JsonProviders.createReader(new StringReader(bodyastring));
return BatchError.fromJson(jsonReader);
} catch (IOException e) {
// If the body of the response is not a valid json, return null
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.compute.batch;

import com.azure.compute.batch.models.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.azure.core.exception.HttpResponseException;

public class BatchErrorTests extends BatchClientTestBase {

@Test
public void testResizeErrorCases() {
try {

BatchPoolResizeContent resizeContent = new BatchPoolResizeContent();
batchClient.resizePool("fakepool", resizeContent);
} catch (HttpResponseException err) {

BatchError error = BatchError.fromException(err);
Assertions.assertNotNull(error);
Assertions.assertEquals("MissingRequiredProperty", error.getCode());
Assertions.assertTrue(
error.getMessage().getValue().contains("A required property was not specified in the request body."));
Assertions.assertEquals("targetDedicatedNodes and/or targetLowPriorityNodes",
error.getValues().get(0).getValue());
}

try {

batchClient.resizePool("fakepool",
new BatchPoolResizeContent().setTargetDedicatedNodes(1).setTargetLowPriorityNodes(1));
} catch (HttpResponseException err) {

BatchError error = BatchError.fromException(err);
Assertions.assertNotNull(error);
Assertions.assertEquals("PoolNotFound", error.getCode());
Assertions.assertTrue(error.getMessage().getValue().contains("The specified pool does not exist."));
Assertions.assertNull(error.getValues());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.compute.batch.models;

import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.HttpResponse;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class BatchErrorUnitTest {

@Test
public void testFromExceptionWithValidJson() throws IOException {
// Arrange
String json = "{\"code\":\"InvalidRequest\",\"message\":{\"value\":\"Invalid request\"},\"values\":[]}";
HttpResponse response = mock(HttpResponse.class);
when(response.getBodyAsString()).thenReturn(Mono.just(json));
HttpResponseException exception = new HttpResponseException("Error", response);

// Act
BatchError batchError = BatchError.fromException(exception);

// Assert
assertNotNull(batchError);
assertEquals("InvalidRequest", batchError.getCode());
assertNotNull(batchError.getMessage());
assertEquals("Invalid request", batchError.getMessage().getValue());
assertTrue(batchError.getValues().isEmpty());
}

@Test
public void testFromExceptionWithValidJsonMultiValues() throws IOException {
// Arrange
String json
= "{\"code\":\"InvalidRequest\",\"message\":{\"value\":\"Error message\"},\"values\":[{\"key\": \"key1\",\"value\":\"value1\"},{\"key\": \"key2\",\"value\":\"value2\"}]}";
HttpResponse response = mock(HttpResponse.class);
when(response.getBodyAsString()).thenReturn(Mono.just(json));
HttpResponseException exception = new HttpResponseException("Error", response);

// Act
BatchError batchError = BatchError.fromException(exception);

// Assert
assertNotNull(batchError);
assertEquals("InvalidRequest", batchError.getCode());
assertNotNull(batchError.getMessage());
assertEquals("Error message", batchError.getMessage().getValue());
assertNotNull(batchError.getValues());
assertEquals("key1", batchError.getValues().get(0).getKey());
assertEquals("value1", batchError.getValues().get(0).getValue());
assertEquals("key2", batchError.getValues().get(1).getKey());
assertEquals("value2", batchError.getValues().get(1).getValue());
}

@Test
public void testFromExceptionWithInvalidJson() {
// Arrange
String invalidJson = "Invalid JSON";
HttpResponse response = mock(HttpResponse.class);
when(response.getBodyAsString()).thenReturn(Mono.just(invalidJson));
HttpResponseException exception = new HttpResponseException("Error", response);

// Act
BatchError batchError = BatchError.fromException(exception);

// Assert
assertNull(batchError);
}

@Test
public void testFromExceptionWithNullResponse() {
// Arrange
HttpResponse response = mock(HttpResponse.class);
when(response.getBodyAsString()).thenReturn(Mono.empty());
HttpResponseException exception = new HttpResponseException("Error", response);

// Act
BatchError batchError = BatchError.fromException(exception);

// Assert
assertNull(batchError);
}
}