/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.framework.servlet; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.mifos.framework.exceptions.PageExpiredException; import org.mifos.rest.approval.service.RESTCallInterruptException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.springframework.webflow.execution.repository.FlowExecutionRestorationFailureException; import org.mifos.reports.pentaho.util.JNDIException; public class UncaughtExceptionHandler extends SimpleMappingExceptionResolver { private static final Logger logger = LoggerFactory.getLogger(UncaughtExceptionHandler.class); @Override protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = checkForAccessDenied(ex, request); if (modelAndView == null) { modelAndView = checkForPageJndiException(ex, request); } if ( modelAndView == null ){ modelAndView = checkForPageExpiredException(ex, request); } if ( modelAndView == null ) { modelAndView = checkForMaxUploadSizeExceededException(ex, request); } if (request.getRequestURI().endsWith("json")) { if (modelAndView == null && ex instanceof RESTCallInterruptException) { // should move to explicit @ExceptionHandler(RESTCallInterruptException) controller method modelAndView = new ModelAndView(); modelAndView.addObject("status", "interrupt"); modelAndView.addObject("approvalId", ((RESTCallInterruptException) ex).getApprovalId()); modelAndView.addObject("cause", "The call has been interrupt for approval"); return modelAndView; } if (modelAndView == null || ex instanceof AccessDeniedException ) { // should move to explicit @ExceptionHandler(Exception) controller method modelAndView = new ModelAndView(); modelAndView.addObject("status", "error"); modelAndView.addObject("cause", ex.getMessage()); logger.error("REST API exception : URI '" + request.getRequestURI() + "'", ex); return modelAndView; } } if (modelAndView == null) { modelAndView = super.doResolveException(request, response, handler, ex); } if (modelAndView != null && !"HEAD".equals(request.getMethod())) { String requestUri = request.getRequestURI(); logger.error("Uncaught exception while accessing '" + requestUri + "'", ex); modelAndView.addObject("uncaughtException", ex); modelAndView.addObject("requestUri", requestUri); if (ex != null) { Writer result = new StringWriter(); ex.printStackTrace(new PrintWriter(result)); modelAndView.addObject("stackString", result.toString()); } } return modelAndView; } private ModelAndView checkForAccessDenied(Exception ex, HttpServletRequest request) { if (ex instanceof AccessDeniedException) { ModelAndView modelAndView = null; String viewName = determineViewName(ex, request); if(viewName != null) { modelAndView = getModelAndView(viewName, ex, request); } return modelAndView; } if (ex.getCause() != null && ex.getCause() instanceof Exception) { return checkForAccessDenied((Exception) ex.getCause(), request); } return null; } private ModelAndView checkForPageExpiredException(Exception ex, HttpServletRequest request){ if ( ex instanceof PageExpiredException || ex instanceof FlowExecutionRestorationFailureException){ ModelAndView modelAndView = null; String viewName = determineViewName(ex, request); if (viewName != null){ modelAndView = getModelAndView(viewName, ex, request); } return modelAndView; } if (ex.getCause() != null && ex.getCause() instanceof Exception) { return checkForPageExpiredException((Exception) ex.getCause(), request); } return null; } private ModelAndView checkForPageJndiException(Exception ex, HttpServletRequest request) { if (ex instanceof JNDIException) { ModelAndView modelAndView = null; String viewName = determineViewName(ex, request); if (viewName != null){ modelAndView = getModelAndView(viewName, ex, request); } return modelAndView; } return null; } private ModelAndView checkForMaxUploadSizeExceededException(Exception ex, HttpServletRequest request) { if (ex instanceof MaxUploadSizeExceededException) { ModelAndView modelAndView = null; String viewName = determineViewName(ex, request); if (viewName != null){ modelAndView = getModelAndView(viewName, ex, request); } return modelAndView; } return null; } }