2

My question is simple. Should we or should we not Handle/Catch Exceptions in Sling Models/WCMUsePojos ?

Details:

We have several SlingModels which are calling OSGi service methods, when any exception is thrown we are catching it right upto the SlingModel and then we are doing in the model @PostConstruct method

slingHttpResponse.sendError(500);

This doesn't seem to work for us, the response status is 500(checked in network tab of the browser) but the page loads anyways instead of loading our 500.jsp page or "Internal Server Error Page" that is setup.

Infact what has worked for us is re-throwing the exception to the default handler. This successfully loads the 500.jsp page.

Ex.

@PostConstruct // THIS WORKS
public void init() throws Exception{
   try{
     // Business Logic calling Injected OSGi Service Methods
   }
   catch(Exception e){
     // Log exception and rethrow
     LOG.error("Exception in Model",e);
     throw e;
   }
}

Is the above implementation Ideal? This works for as opposed to below code which DOES NOT WORK FOR US

 @PostConstruct  // THIS DOES NOT WORK PROPERLY
    public void init() throws Exception{
       try{
         // Business Logic calling Injected OSGi Service Methods
       }
       catch(Exception e){
         // Log exception and SEND ERROR
         LOG.error("Exception in Model",e);
         slingHttpResponse.sendError(500);
       }
    }
Oliver
  • 6,152
  • 2
  • 42
  • 75
  • You would not want to send a status code 500 if you can handle the error more elegantly. This might cause a high load on the publishers and ruin the user experience, as error pages are not cached by default. Better would be configurable monitoring and get notifications when things are broken, so things can be fixed promptly. One component should not be the reason for a broken page in most cases. Worst case scenario would be legal requirements regarding data which has to be shown, which might require a very sophisticated error handling. – Florian Salihovic Oct 07 '19 at 08:35
  • If one component is broken we need the whole page to show 500 page that is our requirement. If you read the documentation about response.sendError wrt AEM, it says(read it somewhere sorry don't have the link), "Clears the response buffer(i.e. all previously commited content before the exception say another jsp/htl files content) and reset the response and request and do requestdisptacher.forward to whateever error page is configurred either default or by ACS commons." – Oliver Oct 07 '19 at 08:38
  • You then have to calculate the state of the page before rendering, for example in a Sling filter. Calling `slingHttpResponse.sendError(500);` is basically too late, as the response is partially rendered. In order to safe performance, you could just execute the filter on publishers or calculate the state once and pass it down to the models, which just read from a "read only" state object. – Florian Salihovic Oct 07 '19 at 08:42
  • Well I'm doing response.sendError(500) in my Model. And whether exception is going to occur or not I can tell only when the Model is executed. How can I predetermine in the Filter if the exception is going to come or not. I Would need more details on this @FlorianSalihovic may be post in the answer section of how you have handled exceptions in modes. Also if you see this guy SlingModel Error handling. http://www.6dglobal.com/blog/creating-site-footer-sightly-2015-04-08 In his example for model he just throws all exceptions to default handler in the Models PostConstruct method. – Oliver Oct 07 '19 at 09:03
  • I will sketch out something later, as I am now in the office. – Florian Salihovic Oct 07 '19 at 09:06
  • @dota2pro I'm afraid you haven't read my question clearly. This has nothing to do with HTL. It's about handling exceptions in SlingModels. – Oliver Oct 10 '19 at 16:41

1 Answers1

2

In a normal page the request- and response-object is wrapped several times by most SlingFilters and even by HTL itself. Many of these implementations are just fetching the output of the response, and ignoring the rest (e.g. http-header, status codes, request-attributes, ...).

If you do a simple test (by just rendering your component), you would see that both methods work. If you do it inside a plain core components page, then you still get a 500, but page and component is already rendered.

You have to go with the exception. The drawback is, that it might expose internals to end users. This is a major security risk.

But take a look into the "Component Error Handler" from AEM Commons. Depending on the runmode, it can replace the component with another HTML snippet.

https://adobe-consulting-services.github.io/acs-aem-commons/features/component-error-handler/index.html

Alexander Berndt
  • 1,628
  • 9
  • 17
  • 1
    The response buffer size can be set via OSGi config in the "Apache Felix Jetty Based Http Service". By default this is 24kb, which usually enough for most test pages. So this is usually not the case. Additionally you would get an IOException, that the response was already flushed. You would definitely see this in the error.log. – Alexander Berndt Oct 08 '19 at 07:10
  • I'll say it again we need the whole page to go down when single component fails. so I don't think the component handler is of any use to us. Still Thanks for trying to help out. – Oliver Oct 10 '19 at 16:40
  • @Oliver The question has been answered here above the mention of component error handler. Throwing that exception upto to sling is the only way to make the whole page error out. – Sharath Madappa Oct 12 '19 at 04:23