cancel
Showing results for 
Search instead for 
Did you mean: 

Webscript Exception Handler

alfrescot3ster
Champ in-the-making
Champ in-the-making
Hello!

I want to create an ExceptionHandler or Interceptor to handle any Exception, which got thrown in the java-backed-webscript (in execute(…) function), to prepare proper error messages for the response.

Has Alfresco some build-in methods or annotations to handle this? If not, how could i achieve this?

Best regards!
7 REPLIES 7

romschn
Star Collaborator
Star Collaborator
Could you please share more details about your implementation. Have you written a common controller and from there invoking individual web scripts? Need to have more details.

alfrescot3ster
Champ in-the-making
Champ in-the-making
public class GetExtendedPersonsServiceGet extends AbstractWebScript {
   private ExtendedPersonService extendedPersonService;

   @Override
   public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException {
      Map<String, List<JsonStructure>> extendedPersons = extendedPersonService.getExtendedPersons();

      res.setContentType("application/json");
      res.getWriter().write(new Gson().toJson(extendedPersons));
   }

   public ExtendedPersonService getExtendedPersonService() {
      return extendedPersonService;
   }

   public void setExtendedPersonService(ExtendedPersonService extendedPersonService) {
      this.extendedPersonService = extendedPersonService;
   }
}


Now I want to catch any exception, which will be thrown inside the execute() method and handle a proper response like a error message instead of the Map. And this should be done in all webscripts.
I could do something like:


try{
Map<String, List<JsonStructure>> extendedPersons = extendedPersonService.getExtendedPersons();

res.setContentType("application/json");
res.getWriter().write(new Gson().toJson(extendedPersons));
}catch(Exception ex){
res.getWriter().write("ERROR: " + ex.getMessage());
}


But I don't want to write in all my webscripts try-catch. I want to add an Annotation like '@HandleException' to the execute method(), which handles all things central.
I found Spring AOP, but I don't know if this is the correct way.

alfrescot3ster
Champ in-the-making
Champ in-the-making
I am using Spring AOP now. It looks quite good, but alfresco giving me transaction exceptions and hibernate-context transactionService not set exceptions.

<?xml version='1.0' encoding='UTF-8'?>

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.2.xsd ">
   
   <aop:aspectj-autoproxy />
   
   <bean id="exceptionHandlerAspect" class="xxx.ExceptionHandler" />
</beans>

@Aspect
public class ExceptionHandler {
   @AfterThrowing(pointcut="execution(* xxx.webscript.*.execute(..))", throwing = "ex")
   
   public void handleError(Throwable ex) {
      System.out.println("I DID IT: " + ex.getMessage());
   }
}


He loads this Spring Aspect perfectly, but the server logs this exceptions:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creati
ng bean with name 'retryingTransactionHelper' defined in class path resource [al
fresco/core-services-context.xml]: Cannot resolve reference to bean 'transaction
Service' while setting bean property 'transactionService'; nested exception is o
rg.springframework.beans.factory.BeanCreationException: Error creating bean with
name 'transactionService' defined in class path resource [alfresco/core-service
s-context.xml]: Cannot resolve reference to bean 'transactionManager' while sett
ing bean property 'transactionManager'; nested exception is org.springframework.
beans.factory.BeanCreationException: Error creating bean with name 'transactionM
anager' defined in class path resource [alfresco/hibernate-context.xml]: Invocat
ion of init method failed; nested exception is org.alfresco.error.AlfrescoRuntim
eException: 05180000 A transaction has not be started for method 'getConnectionP
rovider' on org.hibernate.engine.SessionFactoryImplementor
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveReference(BeanDefinitionValueResolver.java:334)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1418)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.populateBean(AbstractAutowireCapableBeanFactory.java:1159)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:458)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:293)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe
an(AbstractBeanFactory.java:290)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:191)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveReference(BeanDefinitionValueResolver.java:328)
        … 48 more


Someone has ANY idea???

mrogers
Star Contributor
Star Contributor
In general you can't handle exceptions within webscripts. 

Alfresco has an open transaction and expects and needs the exception to complete the rollback.  

You may be able to catch and rethrow the exception.

You can probably also write a custom error response template for the webscript that will have the exception available upon it.   However it is a long time since I tried doing that.

alfrescot3ster
Champ in-the-making
Champ in-the-making
Ah okay '.. needs the exception to complete the rollback.', that was the keypoint for me. thanks. Smiley Wink

I will do a standard try-catch thing and response a custom error message to the frontend. sometimes it's easier to use the standard way.

romschn
Star Collaborator
Star Collaborator
In web scripts, you can also throw WebScriptException passing the appropriate status code and the relevant message.
Web Script framework will render the default response template for the status code you have provided.
Just an example -
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Mandatory parameters not provided");


Hope this helps.

alfrescot3ster
Champ in-the-making
Champ in-the-making
I have tried several ways yet:

Throwing exceptions like 'NullPointerException' and catch in the webscript, this is not working, because of Transaction Exception. It looks like Alfresco recognizes the throw of exceptions and won't do anything afterwards (even if I catch it or rethrow it).
Now I tried it with custom exceptions (extend Exception), this is working perfectly (throwing it anywhere inside the webscript and catch it, to response a custom error message).

The problem is now: this does not help me a lot, because I have to catch the 'real' exceptions, which are occur at runtime to render a proper response.

The way with default response templates does not help me, because I need the real exception to get information about it. I don't want to render an error template like "a error occured".