Commit a58e9bce authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

712: Implement error handling

Task-Url: https://minfba.de.dariah.eu/mantisbt/view.php?id=712
parent 4cb2313b
package eu.dariah.de.dariahsp.sample.controller;
import java.io.IOException;
import java.util.List;
import javax.activity.InvalidActivityException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
......@@ -26,27 +14,18 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import eu.dariah.de.dariahsp.configuration.ConditionalSamlSecurityConfiguration;
import eu.dariah.de.dariahsp.local.LocalUserConf;
import eu.dariah.de.dariahsp.web.AuthInfoHelper;
import eu.dariah.de.dariahsp.web.RedirectCache;
@Controller
@RequestMapping(value="")
public class HomeController {
@Autowired private ServletContext servletContext;
@Autowired private RedirectCache redirectCache;
@Autowired private ServletContext servletContext;
@Autowired private AuthInfoHelper authInfoHelper;
@Autowired private PropertySourcesPlaceholderConfigurer conf;
@Value("#{environment.saml?environment.saml:false}")
private boolean saml;
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
@RequestMapping(value = {"", "/", "/protected/home", "/overprotected/home"}, method = RequestMethod.GET)
public String getHome(HttpServletResponse response) throws IOException {
return "home";
}
......@@ -68,9 +47,7 @@ public class HomeController {
@RequestMapping(value = {"/throw/{code}", "/throw"}, method = RequestMethod.GET)
public void throwError(@PathVariable(required=false) Integer code, HttpServletRequest request, HttpServletResponse response) throws Exception {
//response.sendError(code==null?HttpStatus.NOT_FOUND.value():code);
throw new Exception();
throw new Exception("This is an expected error.");
}
@RequestMapping(value = "/login", method = RequestMethod.GET)
......@@ -82,10 +59,6 @@ public class HomeController {
if (error != null) {
model.addAttribute("error", true);
}
//requestCache.saveRequest(request, response);
String ctx = servletContext.getContextPath();
if (url.startsWith(ctx)) {
......
package eu.dariah.de.dariahsp.sample.exceptions;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.opensaml.common.SAMLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.web.WebAttributes;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import eu.dariah.de.dariahsp.exceptions.UserCredentialsException;
/**
......@@ -33,67 +27,69 @@ public class SampleExceptionController {
protected static final Logger logger = LoggerFactory.getLogger(SampleExceptionController.class);
@RequestMapping(value = {"", "/"}, method = {RequestMethod.GET, RequestMethod.POST })
public ModelAndView renderErrorPage(HttpServletRequest httpRequest) {
ModelAndView errorPage = new ModelAndView("error");
String errorMsg = "";
public String renderErrorPage(Model m, HttpServletRequest httpRequest) {
String errorHeading = "";
String errorDetail = null;
String errorLevel = "warning";
boolean hideHelpText = false;
Throwable e = null;
int httpErrorCode = getErrorCode(httpRequest);
switch (httpErrorCode) {
case 400: {
errorMsg = "Http Error Code: 400. Bad Request";
break;
}
case 401: {
errorMsg = "Http Error Code: 401. Unauthorized";
break;
}
case 403: {
errorMsg = "Http Error Code: 403. Forbidden";
break;
}
case 404: {
errorMsg = "Http Error Code: 404. Resource not found";
break;
}
default: {
errorMsg = "Internal Server Error";
break;
}
case 400: {
errorHeading = "Error 400: Bad Request";
break;
}
case 401: {
errorHeading = "Error 401: Unauthorized";
hideHelpText = true;
errorDetail = "Your account is not authorized for this action. Please contact the DARIAH-DE Helpdesk to seek support.";
break;
}
case 403: {
errorHeading = "Error 403: Forbidden";
hideHelpText = true;
errorDetail = "Your account does not have sufficient privileges. Please contact the DARIAH-DE Helpdesk to seek support.";
break;
}
case 404: {
errorHeading = "Error 404: Resource not found";
break;
}
default: {
errorHeading = "Internal Server Error";
break;
}
}
if (httpRequest.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION)!=null) {
Exception authEx = (Exception)httpRequest.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
if (authEx.getCause()!=null && authEx.getCause() instanceof SAMLException) {
errorPage.addObject("exception", authEx.getCause());
errorMsg = "A SAML/Shibboleth related error has occurred. Please try again later. If the problem persists, please notify support.";
e = authEx.getCause();
errorDetail = "A SAML/Shibboleth related error has occurred. Please try again later. If the problem persists, please notify support.";
errorLevel = "error";
}
if (authEx instanceof UserCredentialsException) {
errorMsg = authEx.getMessage();
errorPage.addObject("exception", authEx);
e = authEx;
}
} else {
errorPage.addObject("exception", this.getException(httpRequest));
e = getException(httpRequest);
}
errorPage.addObject("errorMsg", errorMsg);
errorPage.addObject("url", httpRequest.getRequestURL());
return errorPage;
}
private void handleSAMLException(SAMLException exception) {
// Special exception: IDP Authentication too old, needs refresh
if (exception.getCause()!=null && exception.getCause() instanceof CredentialsExpiredException) {
m.addAttribute("exception", e);
m.addAttribute("errorHeading", errorHeading);
m.addAttribute("errorDetail", errorDetail);
m.addAttribute("errorLevel", errorLevel);
m.addAttribute("hideHelpText", hideHelpText);
if (e!=null) {
m.addAttribute("errorMsg", e.getMessage());
}
m.addAttribute("url", httpRequest.getRequestURL());
return "error";
}
private Exception getException(HttpServletRequest httpRequest) {
if (httpRequest.getAttribute("javax.servlet.error.exception")==null) {
......
......@@ -9,9 +9,9 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
@ControllerAdvice
public class SampleExceptionHandler {
......@@ -22,24 +22,25 @@ public class SampleExceptionHandler {
@ResponseStatus(HttpStatus.CONFLICT) // 409
@ExceptionHandler(InvalidActivityException.class)
public void handleConflict() {
// Nothing to do
System.out.println("ex");
// Nothing to do, just to show how individual errors could be handled
}
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
// If the exception is annotated with @ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)
throw e;
@ExceptionHandler(value = Exception.class)
public String defaultErrorHandler(Model m, HttpServletRequest req, Exception e) throws Exception {
// If the exception is annotated with @ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
// Otherwise setup and send the user to a default error-view.
ModelAndView mav = new ModelAndView();
mav.addObject("errorMsg", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
// Otherwise setup and send the user to a default error-view.
m.addAttribute("errorHeading", "An internal server error has occurred");
m.addAttribute("errorMsg", e.getMessage());
m.addAttribute("url", req.getRequestURL());
m.addAttribute("exception", e);
return DEFAULT_ERROR_VIEW;
}
}
......@@ -25,12 +25,20 @@
<li class="active">Home</li>
</ul>
<div id="main-content">
<h2>Error</h2>
<p>
${errorMsg}
</p>
<h2>${errorHeading}</h2>
<c:if test="${errorMsg!=null}">
<p>
<em>Message</em>: ${errorMsg}
</p>
</c:if>
<c:if test="${errorDetail!=null}">
<div class="alert alert-${errorLevel==null ? 'error' : errorLevel}" role="alert">${errorDetail}</div>
</c:if>
<pre>Failed URL: ${url}
<c:if test="${hideHelpText==null||hideHelpText==false}">
<p>Please try to reproduce the steps that led to this error and notify the DARIAH-DE helpdesk if the problem persists</p>
</c:if>
<pre style="display: none;">Failed URL: ${url}
Exception: ${exception.message}
<c:forEach items="${exception.stackTrace}" var="ste">
${ste}</c:forEach>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment