Skip to content

Commit 130da4f

Browse files
authored
Handle AwsServiceExceptions thrown by handlers (#306)
* Handle AwsServiceExceptions thrown by handlers * Add missing AwsServiceException import statement
1 parent 1c19708 commit 130da4f

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

python/rpdk/java/templates/generate/HandlerWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package {{ package_name }};
33

44
import com.amazonaws.AmazonServiceException;
5+
import software.amazon.awssdk.awscore.exception.AwsServiceException;
56
import software.amazon.awssdk.regions.PartitionMetadata;
67
import software.amazon.awssdk.regions.Region;
78
import software.amazon.cloudformation.Action;
@@ -100,7 +101,7 @@ public void testEntrypoint(
100101
response = invokeHandler(proxy, payload.getRequest(), payload.getAction(), payload.getCallbackContext());
101102
} catch (final BaseHandlerException e) {
102103
response = ProgressEvent.defaultFailureHandler(e, e.getErrorCode());
103-
} catch (final AmazonServiceException e) {
104+
} catch (final AmazonServiceException | AwsServiceException e) {
104105
response = ProgressEvent.defaultFailureHandler(e, HandlerErrorCode.GeneralServiceException);
105106
} catch (final Throwable e) {
106107
e.printStackTrace();

src/main/java/software/amazon/cloudformation/LambdaWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.apache.commons.lang3.exception.ExceptionUtils;
4040
import org.json.JSONObject;
4141
import org.json.JSONTokener;
42+
import software.amazon.awssdk.awscore.exception.AwsServiceException;
4243
import software.amazon.awssdk.http.SdkHttpClient;
4344
import software.amazon.awssdk.http.apache.ApacheHttpClient;
4445
import software.amazon.awssdk.utils.StringUtils;
@@ -361,7 +362,7 @@ public void handleRequest(final InputStream inputStream, final OutputStream outp
361362
publishExceptionMetric(request.getAction(), e, e.getErrorCode());
362363
logUnhandledError(e.getMessage(), request, e);
363364
return ProgressEvent.defaultFailureHandler(e, e.getErrorCode());
364-
} catch (final AmazonServiceException e) {
365+
} catch (final AmazonServiceException | AwsServiceException e) {
365366
publishExceptionMetric(request.getAction(), e, HandlerErrorCode.GeneralServiceException);
366367
logUnhandledError("A downstream service error occurred", request, e);
367368
return ProgressEvent.defaultFailureHandler(e, HandlerErrorCode.GeneralServiceException);

src/test/java/software/amazon/cloudformation/LambdaWrapperTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.mockito.Mock;
4444
import org.mockito.junit.jupiter.MockitoExtension;
4545
import software.amazon.awssdk.http.SdkHttpClient;
46+
import software.amazon.awssdk.services.cloudwatchlogs.model.CloudWatchLogsException;
4647
import software.amazon.cloudformation.exceptions.ResourceAlreadyExistsException;
4748
import software.amazon.cloudformation.exceptions.ResourceNotFoundException;
4849
import software.amazon.cloudformation.exceptions.TerminalException;
@@ -720,6 +721,40 @@ public void invokeHandler_throwsAmazonServiceException_returnsServiceException()
720721
}
721722
}
722723

724+
@Test
725+
public void invokeHandler_throwsSDK2ServiceException_returnsServiceException() throws IOException {
726+
wrapper.setInvokeHandlerException(CloudWatchLogsException.builder().build());
727+
728+
wrapper.setTransformResponse(resourceHandlerRequest);
729+
730+
try (final InputStream in = loadRequestStream("create.request.json");
731+
final OutputStream out = new ByteArrayOutputStream()) {
732+
final Context context = getLambdaContext();
733+
734+
wrapper.handleRequest(in, out, context);
735+
736+
// verify initialiseRuntime was called and initialised dependencies
737+
verifyInitialiseRuntime();
738+
739+
// all metrics should be published, once for a single invocation
740+
verify(providerMetricsPublisher, times(1)).publishInvocationMetric(any(Instant.class), eq(Action.CREATE));
741+
verify(providerMetricsPublisher, times(1)).publishDurationMetric(any(Instant.class), eq(Action.CREATE), anyLong());
742+
743+
// failure metric should be published
744+
verify(providerMetricsPublisher, times(1)).publishExceptionMetric(any(Instant.class), any(),
745+
any(CloudWatchLogsException.class), any(HandlerErrorCode.class));
746+
747+
// verify that model validation occurred for CREATE/UPDATE/DELETE
748+
verify(validator, times(1)).validateObject(any(JSONObject.class), any(JSONObject.class));
749+
750+
// verify output response
751+
verifyHandlerResponse(out,
752+
ProgressEvent.<TestModel, TestContext>builder().errorCode(HandlerErrorCode.GeneralServiceException)
753+
.status(OperationStatus.FAILED)
754+
.message("some error (Service: null; Status Code: 0; Error Code: null; Request ID: null)").build());
755+
}
756+
}
757+
723758
@Test
724759
public void invokeHandler_throwsResourceAlreadyExistsException_returnsAlreadyExists() throws IOException {
725760
// exceptions are caught consistently by LambdaWrapper

0 commit comments

Comments
 (0)