Java Exception Translator Utility - java

I have a typical RESTful web service with two layers. A resource layer and a service layer. The DAO layer seems obsolete with modern object relational mapping libraries.
I am using Google Cloud Endpoints which not surprisingly returns HTTP errors in the form of Java Exceptions. I have a dedicated set of Exceptions the service layer can throw, such as an Object Not Found Exception, from the object relational mapping library, and other internal exceptions. Suffice to say, each internal exception has an HTTP Exception counterpart.
In order for a resource to safely call a service method, the call is surrounded in a series of try catches.
try {
resourceObject = CorrespondingService.method(...);
} catch (InternalExceptionOne internalExceptionOne) {
throw new CorrespondingWebExcpetionOne(internalExceptionOne.getMessage());
} catch (InternalExceptionTwo internalExceptionTwo) {
throw new CorrespondingWebExcpetionTwo(internalExceptionTwo.getMessage());
} catch (InternalExceptionThree internalExceptionThree) {
throw new CorrespondingWebExcpetionThree(internalExceptionThree.getMessage());
}
Since every call to a service method from the resource layer must be wrapped in the same series of try catch statements this creates a lot of repeated code.
I was looking to create a Utility that could act as a WebExcpetionTranslator, but I would have to pass it a method to be run under a try catch. Not sure how to pass a method and parameters, and then how to subsequently call said passed method.
This seems a bit sloppy though? Its there any thing out there that might do this with annotations?
How can I pass a method and arbitrary parameters to a utility method, and subsequently call the passed method with the parameters?
What about annotations? Can you make a custom annotation to handle different exceptions?
P.S. My technology stack is GAE, Objectify, and Google Cloud Endpoints.

Related

Axon framework: Handling database exceptions in state-stored aggregates

I am new to Axon framework and am trying to implement an application using CQRS with state-stored aggregates. The application relies on a database constraint (using H2 for now) to enforce uniqueness on a name attribute. I would like to catch this exception and rethrow it as a user-friendly domain exception.
Per the Axon documentation:
Exception Handling says "an #ExceptionHandler will only handle exceptions thrown from message handling functions in the same class"
Message Intercepting documentation says "A function annotated with #ExceptionHandler will be regarded as a handler interceptor which will only be invoked for exceptional results. Using annotated functions to this end for example allow you to throw a more domain specific exception as a result of a thrown database/service exception."
But I cannot get this to work. I have tried adding exception handlers as follows:
#ExceptionHandler
public void handle(ConstraintViolationException ex) throws Exception {
if (ex.getMessage().contains("UNQ_COMPANY_ID") || ex.getMessage().contains("UNQ_PLAN_NAME")) {
throw new DomainException("Plan name and company id must be unique");
}
throw ex;
}
but this method is not called. I have tried putting the exception handler method on the aggregate and on a separate command handler class, tried adding resultType=ConstraintViolationException.class, and tried catching other types of exceptions including Exception, RuntimeException, AxonServerRemoteCommandHandlingException, etc. but this method is never called.
I can see the error in the log output:
org.axonframework.axonserver.connector.command.AxonServerRemoteCommandHandlingException: An exception was thrown by the remote message handling component: org.hibernate.exception.ConstraintViolationException: could not execute statement
Is it possible to catch database exceptions in state-stored aggregates? If it is, can someone point me towards what I am doing wrong?
The statement "an #ExceptionHandler will only handle exceptions thrown from message handling functions in the same class" makes me wonder whether I need to create a custom repository class (rather than using the default GenericJpaRepository) but that seems like a lot more work than should be necessary.
Thank you!
Update: I was able to roughly accomplish what I want by adding a UnitOfWork parameter to the #CommandHandler method and using it to registering a rollback callback on it as follows:
uow.onRollback(unit -> {
DefaultUnitOfWork duow = (DefaultUnitOfWork) unit;
Throwable ex = duow.getExecutionResult().getExceptionResult();
while (ex != null) {
if (ex.getMessage().contains("UNQ_PLAN_NAME")) {
throw new RuntimeException("Plan name must be unique");
}
ex = ex.getCause();
}
});
But this seems kind of verbose, as well as limiting me to throwing unchecked exceptions only. This also doesn't feel like the right way to do this though because I assume the purpose of the #ExceptionHandler annotation is to eliminate need for code like the above.
This is doable of course.
Actually, the best pointer I could give you if the code-samples repo where you can see a sample about distributed exceptions.
In general, as you could see in your shared log, the 'original' exception is wrapped into an AxonServerRemoteCommandHandlingException meaning you will have to handle that. Doing that, you can pretty much add anything to the details field of this class, adding the indication you had a ConstraintViolationException for example (or an ERROR_CODE, like HTTP protocol does) and you are fine to unwrap it on the other side.
What might be the "gotcha" you require, is to know that an #ExceptionHandler annotated method should reside in the object handling the message. So if you want to react to a failing command handling operation (which would be the case in your sample), you will need to place the exception handler in the Aggregate, next to the Command Handler.
That fact you get an AxonServerRemoteCommandHandlingException to me suggests the exception is caught on the command dispatching end. So, prior to dispatching a command on the CommandGateway/CommandBus.
However, whether this is the problem at hand, isn't clear to me right now, since the sample only shows the exception handler and not where it resides. Please share whether my assumption on the placement of the exception handler is correct. If not, we'll dive into this deeper to get to the cause.

Can we handle a exception from dao layer to presentation layer without impacting the service layer(no modification in service layer)

The scenario is like I wrote a MVC-based application:
Controller - Service - DAO layer. Now I got an exception in DAO layer and I want to handle that exception in presentation layer so that service layer needs no change.
Because by using regular try/catch or throws it has to pass through the service layer which I don't want.
Is there any better approach to achieve it?
class Controller{
method1(){}
}
class service(){
method1Serice(){}
}
class DAO(){
method1DAO(){
// exception occurs here
}
You can have the DAO class throw an unchecked exception. (any subclass of RuntimeException will do). You can create your own custom exception or use any of the predefined ones. just make sure the Service doesn't catch Throwable and you can have the Controller catch it.
You can extend your exception class from RuntimeException so that compiler does not complain about exception handling. You can then catch that exception in the presentation layer.
Perhaps you are looking for Controller Based Exception Handling, you can check these in Exception Handling in Spring MVC and also Error Handling for REST with Spring.
#ExceptionHandler(YourException.class)
public String handleException(){
logger.info(message);
return "database_error";
}
Actually I would suggest you handle the exceptions properly in Service-Layer and encapsulate that exception properly to return to the front-user via Controller-Layer.
Normally, checked exceptions are carrying some meaningful messages which can be used to do recovery or let the caller explicitly handle it properly. Try not to directly avoid it since it's there.
As I understand it, a data access object (DAO) is intended for transferring data between the server and the client. I'm assuming that the client is what you refer to as the presentation layer. In other words, the part that the end user interacts with. As such, the DAO should contain fields and accessor methods only, i.e. it should not contain logic. Hence it should not contain methods that may throw exceptions. So I would suggest perhaps re-designing your application. Otherwise, perhaps you can provide more detailed code?

Converting Complex Component Interface to Standard Web Service [Java]

I have component that has complex interface with operations accepting non-primitive data or simple POJO.
What is the best practice (ways/methodologies) to convert this component interface to be standard Web Service interface that can be consumed by java and non-java clients, so that the service consumer can generate classes without problem using WSDL.
Can be used as it's? if not, is there a way to minimal change it without affecting operations' behavior?
The component interface has operations like:
/** This is asynchronous method that needs to callback the ResultHandler
interface which has to be implemented by the component user to handle
operationOne result **/
public void operationOne(int id, ResultHandler handler);
/** I think there is no problem with the following operation for Web Services,
when using data contracts. Correct me if I’m wrong! **/
public String operationTwo(int id, MyObject obj);
The ResultHandler interface:
/** Note that this handler interface contains InputStream
and Exception as parameters for the handling methods **/
interface ResultHandler {
void onComplete(InputStream is);
void onFailure(IOException ioEx);
}
You can use your objects in the webmethods, as they are converted to complex WSDL types, but keep in mind that this can only be done to a degree. You should have simple POJO's to transmit the data structures so that you get the benefit of the WSDL/code generation not the complex types you will be using to perform your business duties. Also a peace of advice, should REST/JSON over SOAP Web Services.
UPDATE:
The only way to effectively test your web services is by creating a moke for every call you have on your web service.
Moq - How to mock web service call?
You need to make a method that can invoke the component with the provided arguments and return a complete response. For best results that method should not have side-effects.
Then add #WebService and #WebMethod annotations to it, and use Endpoint.publish(...) to create a small stand alone application publishing that web service. The JAX-WS stack in Java 6 can autogenerate the WSDL from this.
See http://java.dzone.com/articles/jax-ws-hello-world for a full tutorial for doing this.

Should Service layer throw an exception?

I don't like throwing exceptions for some reason, maybe because of the performance hit I don't know, wondering if I should re-think this issue.
Should my service layer (uses Dao's + business logic etc.) be throwing exceptions?
public ModelAndView createProduct(#Valid ProductForm productForm, ..) {
ModelAndView mav = new ModelAndView(...);
if(bindingResult.hasErrors()) {
return mav;
}
// throw exception if user doesn't have permissions??
productService.create(product, userPermissions);
}
So my options in the create method of the ProductService:
if the user doesn't have permissions, throw an exception
return some sort of a Response object that will have the new product Id if it was a success, along with a success/failure flag and a error collection.
Things to keep in mind:
I may re-use this service layer in a non-web app, also in a restful web service.
What is considered best practice?
Depends of what you mean by service and exception, but in the context you've got I'll assume a java exception from a HTTP endpoint.
The answer is no. Services should expose errors in a general way. In the case of Restful service, errors should be propagated as HTTP status with error codes. The service shouldn't leak implementation details to consumers. It's a natural boundary.
The Consumer should handle those error situations and decide the most appropriate what to communicate that. It may well choose to generate an exception. But these exceptions are disjoint from the original issue/eception that caused the service to return an error code.
Going further I would say #yahir is right in what he says also. HTTP service would expose HTTP errors, and it may well just be using another service underneath that returns another kind of errors, but it's job will be to handle or map them appropriately.
Ask yourself what other options do you have, sometimes exceptions are necessary. The only other thing you could do is return a status of failure or success and handle appropriately.
I'd say the service layer should behave just like any other method exposed to client code. After all, that's exactly what it is.
Clients that will use it through RPC, will expect exactly this behavior.
Other cilents, such as REST, should anyway access the services layer through some other wrapping layer (e.g. Controller layer). One of this wrapping layer duties is transforming the response to be client-consumable.

The best way of exception handling in an app with web services

I have an application which consists of SOAP and REST web services and a simple HTTP access. All of them convert incoming requests and send them to a handler. The most painful thing is exception handling. In order to return the right response, I have to wrap every method with try-catch block and create a response there.
I thought that I could create a filter which could do it. But how can the filter recognise the source of it (soap, rest frontend) so I knew that I should return a SOAP or other response?
It depends on the WS framework you use. All I know have some sort of interceptors/aspects that you can inject and handle exceptions in one place. For instance in apache-cxf there is even a special outbound error chain where you can plug your own interceptors.
Obviously try-catch in every method is a bad idea.
In layer of below Web-Service Layer, you have to create your custom Exception and in Web-Service layer you have to use try-catch approach for achieve occurred exception and in catch block log and convert it to your custom web service layer exception. I show this approach in following:
#WebService
public class EmployeeWS
{
#WebMethod
public void add(Employee em) throws CustomWebServiceException
{
try
{
// call facade layer method
}
catch(Exception e)
{
logger.error(e.getMessage());
throw new CustomWebServiceException(e);
}
}
}
Alternative using try catch in any Web-Method,you can use AOP approch(for sample Spring AOP) or interceptor approach in Web-Service frameworks(for sample SOAPHandler<T> in JAX-WS).
Note: In JAX-WS standard, you can't throw a RuntimeException because Exception must specify in final WSDL and if you throw a RuntimeException your web service client don't achieve your CustomException, in another your Web-Methodneed to throws in itself signature.
You can see selected Web-Service faramework documents for more information.
It sounds that you are not using any framework because that was typical frameworks provide. For example Spring allows you to decouple the code from exception handling and define your custom exception handlers.
In your case you generally have 2 solutions.
(1) You can use Decorator pattern: wrap each service with decorator where each method is implemented as
try {
call real method
} catch() {
send error to client
}
Since it is very verbose you can save time using Dynamic proxy (feature that was introduced in java 5). So, you can dynamically wrap each service (if your services have defined interface).
(2) You can solve it using servlet API's error page:
javax.servlet.ServletException
/servlet/ErrorDisplay
for more details see http://java.sun.com/developer/technicalArticles/Servlets/servletapi2.3/
You can customize your class!! Do it!
Take easy on diagnostic errors, like insert a protocol number, message Log, message client, etc...
http://java.globinch.com/enterprise-java/web-services/jax-ws/jax-ws-exceptions-faults-annotation-exception-and-fault-handling-examples/#Pre-Requisites

Categories

Resources