문제

Anyone know why the following code failed to capture the exception?

package org.rythmengine.spring.web.servlet.view;

import org.rythmengine.RythmEngine;
import org.rythmengine.exception.RythmException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class RythmExceptionHandler {

    RythmEngine engine;

    @Autowired
    public RythmExceptionHandler(RythmConfigurer conf) {
        this.engine = conf.getRythmEngine();
    }

    @ExceptionHandler(value = RythmException.class)
    public ModelAndView defaultErrorHandler(RythmException e) throws Exception {
        if (engine.mode().isProd()) {
            throw e;
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.setViewName("errors/500.html");
        return mav;
    }

}
도움이 되었습니까?

해결책

Found the issue. It needs to add one line in the configuration file:

<context:component-scan base-package="org.rythmengine.spring.web.servlet.view"/>

And also need to add @EnableWebMvc annotation in additional to the @ControllerAdvice annotation.

However I can't force user to add the component in their configuration, or I want to make it transparent to user. Thus the solution become the following code:

    if (engine.isDevMode()) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.scan("org.rythmengine.spring.web.servlet.view");
    }

This is not the end so far. It successfully capture the Exception in user's controller code, but not the exception in the view rendering process. I am looking for a way to add HandlerInterceptor so that it can handle error in DispatcherServlet.triggerAfterCompletion(...)

Updates

The above code proved not working. The final solution is adding the following annotation to an arbitrary class:

@Configuration
@ComponentScan("org.rythmengine.spring.web.servlet.view")

And yes, now I don't need user to add the <context:component-scan ...> into their xml configuration file.

With regarding to render time exception handling, I cache the exception internally in the RythmView class in case there are error (usually compile error or parsing error) raised up at checkResource(Locale) call, and in the following renderMergedTemplateModel call I will check if there are cached exception, if there is then render the exception screen, which is something like:

enter image description here

And yes, the developer friendly screen feature is only available when you set devMode to true (which is by default false) for RythmConfigurer:

<bean id="rythmConfig" class="org.rythmengine.spring.web.servlet.view.RythmConfigurer">
    <property name="resourceLoaderPath" value="/WEB-INF/rythm/"/>
    <property name="outputRequestParameters" value="false"/>
    <property name="devMode" value="true"/>
</bean>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top