Reputation: 1224
I'm getting response from external service that looks like:
"status": {
"httpCode": "external service response code, e.g. 201",
"errors": [
{
"code": "error code, e.g. 13",
"message": "e.g. Invalid value for some variable"
},
{
"code": "12",
"message": "Invalid phone number format"
}
]
}
The errors list may have multiple objects. While returning the response from that external service to my frontend application, I'd like to show all the messages. How do I do that? As far as I know Exception related classes only have a single field called message
.
Upvotes: 1
Views: 2469
Reputation: 374
One of the way to customize the Http response for exceptions, by using the Custom Exceptions.
1.Create a custom exception by using RuntimeException
Class
public class SampleException extends RuntimeException {
private List<SampleNestedObject> messages;
public SampleException() {
}
public SampleException(List<SampleNestedObject> messages){
this.messages=messages;
}
}
public class SampleNestedObject {
private int httpCode;
private String message;
//Getters,Setters,Contructors
}
2.Create a response Structure
public class SampleErrorResponse {
private List<SampleNestedObject> messages;
//Getters,Setters,Contructors
}
@ExceptionHandler(SampleException.class)
public final ResponseEntity<Object> handleSampleException(SampleException ex,WebRequest request){
SampleErrorResponse errorResponse=new SampleErrorResponse(ex.getMessages());
return new ResponseEntity(errorResponse,HttpStatus.NOT_FOUND); //Any status code
}
4.Throw exception whenever you want to.
@GetMapping("/getException")
public ResponseEntity<Object> getException(){
List<SampleNestedObject> messages= Arrays.asList(new SampleNestedObject(404,"Sample Message 1"),new SampleNestedObject(404,"Sample Message 2"));
throw new SampleException(messages);
}
Response for the above sample will be,
{
"messages": [
{
"httpCode": 404,
"message": "Sample Message 1"
},
{
"httpCode": 404,
"message": "Sample Message 2"
}
]
}
Hope this will work.
Upvotes: 1
Reputation: 102903
Exceptions are mostly not special, they are just a type definition same as any other. You can have them do whatever you want, as long as they extend Throwable. For example:
public class MaciazServiceException extends Exception {
private final Map<Integer, String> codeToMessageMapping;
public MaciazServiceException(JSON json) {
// code here that pulls code and message apart and makes...
Map<Integer, String> codeToMessageMapping = ....;
this.codeToMessageMapping = codeToMessageMapping;
}
@Override public String getMessage() {
// code here that returns a nice view of the above. For example...
return codeToMessageMapping.entrySet().stream().map(
entry -> entry.getKey() + " = " + entry.getValue())
.collect(Collectors.joining("\n"));
}
// you can define methods too, if you want:
public boolean hasErrorCode(int code) {
return codeToMessageMapping.containsKey(code);
}
}
This can then be used elsewhere:
try {
myMaciazService.doThingie(...);
} catch (MaciazServiceException e) {
if (e.hasErrorCode(MaciazService.ERRORCODE_NOT_AUTHORIZED)) {
userpassView.show();
}
}
Upvotes: 2