harperkej
harperkej

Reputation: 33

@ControllerAdvice not handling thrown exceptions

The repository:

@Repository
public class UserRepositoryImpl implements UserRepository {
@PersistenceContext
public EntityManager entityManager;
public User findUserById(Long id) throws RepositoryException {
    try {
        User foundUser = entityManager.find(User.class, id);
        if (foundUser == null) {
            throw new RepositoryException();
        }
        return foundUser;
    } catch (Exception e) {
        throw new RepositoryException();
    }
}
}

The service class:

@Service
@Transactional(rollbackFor = DataIntegrityViolationException.class)
public class UserServiceImpl implements UserService {

private UserRepository userRepository;

@Autowired
public void setUserRepository(UserRepository userRepository) {
    this.userRepository = userRepository;
}

public User findUserById(Long id) throws ServiceException {
    try {
        return userRepository.findUserById(id);
    } catch (Exception e) {
        throw new ServiceException();
    }
}
}

The controller:

@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findUserbyId(@PathVariable Long id) throws RestApiException {
    try {
        return userService.findUserById(id);
    } catch (Exception e) {
        throw new RestApiException();
    }
}
}

Advice Controller:

@ControllerAdvice
public class AdviceController {
@ExceptionHandler(RepositoryException.class)
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
public ExceptionDetails handleDBException(RepositoryException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("DB", e.getMessage());
    return exceptionDetails;
}

@ExceptionHandler(ServiceException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ExceptionDetails shandleServiceException(ServiceException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("SERVICE", e.getMessage());
    return exceptionDetails;
}

@ExceptionHandler(RestApiException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ExceptionDetails handleRestApiException(RestApiException e) {
    ExceptionDetails exceptionDetails = new ExceptionDetails("REST", e.getMessage());
    return exceptionDetails;
}
}

ExceptionDetails class:

public class ExceptionDetails {

private String code;
private String message;

public ExceptionDetails(String code, String message) {
    this.code = code;
    this.message = message;
}

}

Whenever i a do a request using postman with url :http://localhost:8080/springapp/api/users/7 , where the id doesnt exsist in db, i guess that advice controller should have handled the exception thrown, but i get the following:

Hibernate: 
    select
        user0_.id as id1_3_0_,
        user0_.email as email2_3_0_,
        user0_.registrationId as registra3_3_0_,
        user0_.username as username4_3_0_ 
    from
        User user0_ 
        where
        user0_.id=?
Mar 04, 2016 11:21:23 AM org.apache.catalina.core.StandardWrapperValve     invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path     [/notofatespring] threw exception [Request processing failed; nested     exception is com.adaptiv.notofatespring.exception.RestApiException] with root     cause
com.adaptiv.notofatespring.exception.RestApiException
    at     com.adaptiv.notofatespring.controller.UserController.findUserbyId(UserControl    ler.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at     sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at     sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.    java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at     org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(Invoca    bleHandlerMethod.java:221)
    at     org.springframework.web.method.support.InvocableHandlerMethod.invokeForReques    t(InvocableHandlerMethod.java:136)
    at     org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandler    Method.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAd    apter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
    at     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAd    apter.handleInternal(RequestMappingHandlerAdapter.java:731)
    at     org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handl    e(AbstractHandlerMethodAdapter.java:85)
    at     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServle    t.java:959)
    at     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet    .java:893)
    at     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServ    let.java:968)
    at     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:    859)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at     org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.jav    a:844)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationF    ilterChain.java:303)
    at     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCha    in.java:208)
    at         org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at     org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationF    ilterChain.java:241)
    at     org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCha    in.java:208)
    at     org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.jav    a:220)
    at     org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.jav    a:122)
    at     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.    java:505)
    at     org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at     org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at     org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:    116)
    at     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at     org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Proces    sor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(Abstract    Protocol.java:625)
    at     org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:3    16)
    at     java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:114    2)
at     java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:61    7)
    at     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.jav    a:61)
    at java.lang.Thread.run(Thread.java:745)

Any idea why controller advice is not handling exception?

Upvotes: 1

Views: 7426

Answers (1)

Mudassar
Mudassar

Reputation: 3205

Its most likely that you are missing @EnableWebMvc annotation in your Exception handler. As per my understanding your Exception handler should be like this.

@EnableWebMvc
@ControllerAdvice
public class AdviceController {

Also when declaring you can also provide the packages that it should scan for. eg

@ControllerAdvice(basePackages = {"com.concretepage.controller"} ) 

And for testing purpose if possible you can return just jsp like eg

 

@ExceptionHandler(SQLException.class)

    

public String handleSQLException(HttpServletRequest request, Exception ex){

        logger.info("SQLException Occured:: URL="+request.getRequestURL());

        return "database_error";

    }

     

Upvotes: 1

Related Questions