Reputation: 441
We have a micro service based architecture which consists of main apps server module and libs modules. In main app server, we are just accepting request and providing response via a request and response object on the REST API methods which call service layers available in libs module.
parent--
------apps
---server
---Controller Class
------libs
---core
---Service Layer
---Dao Layer
To propagate the error messages so that they can be send over to clients using Response Object(available only in Controller classes), we are throwing custom exceptions in service layer, so that we can send error message to Controller classes. The problem with this approach is that we are throwing exception in all cases as an example we throw exception even when an input is not correct or when user is not having permission, where in we can just return a response to user with the error message.
My question is that - Is it a correct approach to throw Custom exception just for the sake of propagating error messages from Service layer to Controller? If NO, then how we can propagate error message to controller layer?
Service Layer ---
public String serviceLayerMethod(String param) throws AssetException {
try {
if(param==null){
throw new CustomException;
} else{
return param;
}
} catch (CustomException e) {
LOGGER.error(CustomExceptionEnum.PARAMNULL_EXCEPTION.getMessage(),e);
throw new CustomException(CustomExceptionEnum.PARAMNULL_EXCEPTION.getMessage(), e);
}
}
Controller Layer ---
public Response restAPI(Request request) {
try {
response.setMessage(service.serviceLayerMethod());
response.setSuccess(true);
} catch (CustomException e) {
response.setMessage(e.getMessage());
response.setSuccess(false);
}
return response
}
Upvotes: 2
Views: 3221
Reputation: 10876
As Neville pointed out; this is a debatable topic and nothing is truly right or wrong..
My opinion is that API should be independent of UI.. So, if an exception throws an exception.. its ok to throw it back.. and let the Client handle it or decide what to do with this exception.. Because some clients might want to show a beautiful user friendly message; whlie other client might want the actual message ( for ex. if another algorithm is calling this API ).
Upvotes: 1
Reputation: 29639
This is a complex and subtle topic - it may well be opinion based.
Firstly, avoid using exceptions to communicate application logic. Your example doesn't suggest you're doing this, but often custom exceptions are used to communicate application or domain logic, and handling that in a try/catch block is hard to read, hard to test, and hard to evolve. For instance, if a purchase fails because the customer has exceeded their credit limit (a business rule), I'd avoid using a custom exception to manage that instance.
Secondly, try to use the built-in exceptions, rather than creating your own. Java has several built-in exeptions for parameter validation; you add no value by duplicating them. Only create custom exceptions when you can't find a built-in Java exception.
Thirdly, try to handle application exceptions in the controller layer if you can - pushing everything down into the service layer makes that layer more complicated and harder to test.
Finally, focus on how you communicate your errors to your client - the common pattern is to use HTTP error codes. Eventually, you may end up translating your custom exception to a "HTTP: 500" code, and you want your client applications to be able to reason about those exceptions in a consistent way.
Upvotes: 0
Reputation: 19100
I can't see any problem doing that, but you can do better using the Spring to do this for you on your Rest API.
On Spring, you can use @RestControllerAdvice
and @ExceptionHandler
to catch any exception and return a nice message for the user. Like:
@Slf4j
@RestControllerAdvice
public class ErrorHandlerController {
@ExceptionHandler(CustomException.class)
public ResponseEntity<ApiErrorResponse> handleApiException(CustomException ex, Locale locale) {
log.error("Custom error catch with the code {}", ex.getErrorCode(), ex);
ApiErrorResponse error = new ApiErrorResponse(ex, locale);
return new ResponseEntity<>(error, ex.getHttpStatus());
}
}
Upvotes: 2
Reputation: 437
I think it makes sense to log the error and simply display HTTP error to the error for example BAD_REQUEST or INTERNAL_SERVER_ERROR ...
Upvotes: 0