Skip to content

Commit 164e2d7

Browse files
authored
Merge pull request #1586 from CMSgov/QPPA-11181
QPPA-11181: Resolve edge-case 500 errors
2 parents 853af6a + 8ab02b7 commit 164e2d7

5 files changed

Lines changed: 64 additions & 3 deletions

File tree

commons/src/main/resources/measures-data.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41808,7 +41808,7 @@
4180841808
"nqfEMeasureId": null,
4180941809
"nqfId": null,
4181041810
"measureType": "process",
41811-
"isHighPriority": true,
41811+
"isHighPriority": false,
4181241812
"primarySteward": "Centers for Medicare & Medicaid Services",
4181341813
"isInverse": false,
4181441814
"isRiskAdjusted": false,

rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v1/ExceptionHandlerControllerV1.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import gov.cms.qpp.conversion.model.error.TransformException;
1010

1111
import com.amazonaws.AmazonServiceException;
12+
1213
import org.slf4j.Logger;
1314
import org.slf4j.LoggerFactory;
1415
import org.springframework.http.HttpHeaders;
@@ -18,8 +19,11 @@
1819
import org.springframework.web.bind.annotation.ControllerAdvice;
1920
import org.springframework.web.bind.annotation.ExceptionHandler;
2021
import org.springframework.web.bind.annotation.ResponseBody;
22+
import org.springframework.web.multipart.MultipartException;
2123
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
2224

25+
import gov.cms.qpp.conversion.api.exceptions.BadZipException;
26+
2327
/**
2428
* Modify the controller to send back different responses for exceptions
2529
*/
@@ -102,6 +106,23 @@ ResponseEntity<String> handleInvalidFileTypeException(InvalidFileTypeException e
102106
return new ResponseEntity<>(exception.getMessage(), httpHeaders, HttpStatus.NOT_FOUND);
103107
}
104108

109+
/**
110+
* "Catch" the {@link BadZipException}.
111+
* Return the {@link AllErrors} with an HTTP status 400.
112+
*
113+
* @param exception The BadZipException that was "caught".
114+
* @return The BadZipException message
115+
*/
116+
@ExceptionHandler(BadZipException.class)
117+
@ResponseBody
118+
ResponseEntity<String> handleBadZipException(BadZipException exception) {
119+
API_LOG.error("Zip file is corrupt, incomplete, or invalid.", exception);
120+
HttpHeaders httpHeaders = new HttpHeaders();
121+
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
122+
123+
return new ResponseEntity<>(exception.getMessage(), httpHeaders, HttpStatus.BAD_REQUEST);
124+
}
125+
105126
@ExceptionHandler(AmazonServiceException.class)
106127
@ResponseBody
107128
ResponseEntity<String> handleAmazonException(AmazonServiceException exception) {
@@ -122,6 +143,26 @@ ResponseEntity<String> handleInvalidPurposeException(InvalidPurposeException exc
122143
.body(exception.getMessage());
123144
}
124145

146+
/**
147+
* "Catch" the {@link MultipartException}.
148+
* Return an error message with an HTTP status 400.
149+
*
150+
* @param exception The MultipartException that was "caught".
151+
* @return The error message explaining the malformed multipart request
152+
*/
153+
@ExceptionHandler(MultipartException.class)
154+
@ResponseBody
155+
ResponseEntity<String> handleMultipartException(MultipartException exception) {
156+
API_LOG.error("Malformed multipart request", exception);
157+
HttpHeaders httpHeaders = new HttpHeaders();
158+
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
159+
160+
String message = "Invalid multipart request: " +
161+
(exception.getCause() != null ? exception.getCause().getMessage() : exception.getMessage());
162+
163+
return new ResponseEntity<>(message, httpHeaders, HttpStatus.BAD_REQUEST);
164+
}
165+
125166
private ResponseEntity<AllErrors> cope(TransformException exception) {
126167
HttpHeaders httpHeaders = new HttpHeaders();
127168
httpHeaders.setContentType(MediaType.APPLICATION_JSON);

rest-api/src/main/java/gov/cms/qpp/conversion/api/controllers/v2/ZipController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.stream.Collectors;
99
import java.util.zip.ZipEntry;
10+
import java.util.zip.ZipException;
1011
import java.util.zip.ZipFile;
1112

1213
import org.slf4j.Logger;
@@ -18,6 +19,7 @@
1819

1920
import gov.cms.qpp.conversion.ConversionReport;
2021
import gov.cms.qpp.conversion.api.controllers.SkeletalQrdaController;
22+
import gov.cms.qpp.conversion.api.exceptions.BadZipException;
2123
import gov.cms.qpp.conversion.api.model.ConvertResponse;
2224
import gov.cms.qpp.conversion.api.model.Metadata;
2325
import gov.cms.qpp.conversion.api.services.AuditService;
@@ -53,6 +55,9 @@ protected List<ConvertResponse> respond(MultipartFile file, String checkedPurpos
5355
}
5456
return responses;
5557
} catch (IOException e) {
58+
if (e instanceof ZipException) {
59+
throw new BadZipException("Zip file is corrupt, incomplete, or invalid.");
60+
}
5661
throw new UncheckedIOException(e);
5762
}
5863
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package gov.cms.qpp.conversion.api.exceptions;
2+
3+
/**
4+
* Exception for handling an invalid file type
5+
*/
6+
public class BadZipException extends RuntimeException {
7+
8+
/**
9+
* Constructor to call RuntimeException
10+
* @param message Error response
11+
*/
12+
public BadZipException(String message) {
13+
super(message);
14+
}
15+
}

rest-api/src/test/java/gov/cms/qpp/conversion/api/controllers/v2/ZipControllerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
import java.io.IOException;
1212
import java.io.InputStream;
13-
import java.io.UncheckedIOException;
1413
import java.nio.file.Files;
1514
import java.nio.file.Path;
1615
import java.util.List;
@@ -32,6 +31,7 @@
3231
import gov.cms.qpp.conversion.ConversionReport;
3332
import gov.cms.qpp.conversion.Source;
3433
import gov.cms.qpp.conversion.api.exceptions.AuditException;
34+
import gov.cms.qpp.conversion.api.exceptions.BadZipException;
3535
import gov.cms.qpp.conversion.api.model.ConvertResponse;
3636
import gov.cms.qpp.conversion.api.model.Metadata;
3737
import gov.cms.qpp.conversion.api.services.AuditService;
@@ -120,7 +120,7 @@ void uploadTestQrdaFile() {
120120

121121
@Test
122122
void uploadNullQrdaFile() {
123-
Assertions.assertThrows(UncheckedIOException.class, () -> {
123+
Assertions.assertThrows(BadZipException.class, () -> {
124124
objectUnderTest.uploadQrdaFile(new MockMultipartFile("null.zip", new byte[0]), "Test");
125125
});
126126
}

0 commit comments

Comments
 (0)