Reputation: 83
I am trying to learn microservices and trying to implement them. In which I have created two applications. Consider application-1 as layer-1 and application-2 as layer-2. I have created the below classes to handle exceptions in both layer-1 and layer-2
ErrorDetails
@AllArgsConstructor
@Getter
@Setter
public class ErrorDetails {
private Date timestamp;
private String message;
private String path;
private String application;
}
GlobalExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler{
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(),ex.getMessage(), request.getDescription(false),"DBLayer");
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> globleExcpetionHandler(Exception ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(),ex.getMessage(), request.getDescription(false),"DBLayer");
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
ResourceNotFoundException
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
public ResourceNotFoundException(String message) {
super(message);
}
}
I am getting a proper result if the data is available and I am getting proper exception if the data is unavailable in layer-1 like below.
http://localhost:8080/api/company/1000
{
"timestamp": "2021-11-24T16:33:12.208+00:00",
"message": "company not found with id 1000",
"path": "uri=/api/company/1000",
"application": "DBLayer"
}
In layer-2, I am calling the same service which I am executing in layer-1. I am able to get a proper result if the resource is available, but I am not able to re-throw the same exception with the same response header if the data is unavailable how do I handle this.
public CompanyDto getCompanyById(Long companyId) {
log.info(">> Calling get company by id : ");
final String finalUrl = "http://localhost:8080/api/company/"+companyId;
ResponseEntity<CompanyDto> response= restTemplate.exchange(finalUrl, HttpMethod.GET,ResourceUtil.getNewHttpEntity(null), new ParameterizedTypeReference<CompanyDto>() {});
return response.getBody();
}
As per the below comments, I tried like below its working fine but is there any better way because I may have to add so much throws at method signature
public CompanyDto getCompanyById(Long companyId) throws JsonMappingException, JsonProcessingException, ResourceNotFoundException {
log.info(">> Calling get company by id : "+companyId);
final String finalUrl = "http://localhost:8080/api/company/"+companyId;
ResponseEntity<CompanyDto> response=null;
try {
response= restTemplate.exchange(finalUrl, HttpMethod.GET,ResourceUtil.getNewHttpEntity(null), new ParameterizedTypeReference<CompanyDto>() {});
} catch (HttpStatusCodeException e) {
exceptionCheck(e);
}
return response.getBody();
}
private void exceptionCheck(HttpStatusCodeException e) throws JsonMappingException, JsonProcessingException, ResourceNotFoundException {
ObjectMapper mapper = new ObjectMapper();
String responseString=e.getResponseBodyAsString();
ErrorDetails ed = mapper.readValue(responseString, ErrorDetails.class);
if(e.getRawStatusCode()==404) {
throw new ResourceNotFoundException("kjnj");
}
}
Upvotes: 2
Views: 1358
Reputation: 83
In the second layer, we can the exception in the global exception handler class like below
@ExceptionHandler( {HttpClientErrorException.class, HttpStatusCodeException.class, HttpServerErrorException.class})
@ResponseBody
public ResponseEntity<Object> httpClientErrorException(HttpStatusCodeException e) throws IOException {
BodyBuilder bodyBuilder = ResponseEntity.status(e.getRawStatusCode()).header("X-Backend-Status", String.valueOf(e.getRawStatusCode()));
if (e.getResponseHeaders().getContentType() != null) {
bodyBuilder.contentType(e.getResponseHeaders().getContentType());
}
return bodyBuilder.body(e.getResponseBodyAsString());
}
Upvotes: 1