mirror of https://github.com/halo-dev/halo
Refactor common error render again
parent
f3a42147b9
commit
fffc1c9c7f
|
@ -1,18 +1,22 @@
|
|||
package run.halo.app.controller.core;
|
||||
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.web.ErrorProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
import run.halo.app.exception.HaloException;
|
||||
import run.halo.app.service.ThemeService;
|
||||
import run.halo.app.utils.FilenameUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -34,17 +38,22 @@ public class CommonController extends AbstractErrorController {
|
|||
|
||||
private static final String INTERNAL_ERROR_TEMPLATE = "500.ftl";
|
||||
|
||||
private static final String ERROR_TEMPLATE = "common/error/error";
|
||||
private static final String ERROR_TEMPLATE = "error.ftl";
|
||||
|
||||
private static final String DEFAULT_ERROR_PATH = "common/error/error";
|
||||
|
||||
private final ThemeService themeService;
|
||||
|
||||
private final ErrorProperties errorProperties;
|
||||
|
||||
private final ErrorAttributes errorAttributes;
|
||||
|
||||
public CommonController(ThemeService themeService,
|
||||
ErrorAttributes errorAttributes,
|
||||
ServerProperties serverProperties) {
|
||||
super(errorAttributes);
|
||||
this.themeService = themeService;
|
||||
this.errorAttributes = errorAttributes;
|
||||
this.errorProperties = serverProperties.getError();
|
||||
}
|
||||
|
||||
|
@ -60,17 +69,19 @@ public class CommonController extends AbstractErrorController {
|
|||
|
||||
log.error("Error path: [{}], status: [{}]", getErrorPath(), status);
|
||||
|
||||
// Get the exception
|
||||
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
|
||||
Object throwableObject = request.getAttribute("javax.servlet.error.exception");
|
||||
|
||||
if (throwable != null) {
|
||||
if (throwableObject != null) {
|
||||
Throwable throwable = (Throwable) throwableObject;
|
||||
log.error("Captured an exception", throwable);
|
||||
|
||||
if (StringUtils.startsWithIgnoreCase(throwable.getMessage(), "Could not resolve view with name '")) {
|
||||
// TODO May cause unknown-reason problem
|
||||
// if Ftl was not found then redirect to /404
|
||||
return contentNotFround();
|
||||
return contentNotFound();
|
||||
}
|
||||
|
||||
handleCustomException(request);
|
||||
}
|
||||
|
||||
Map<String, Object> errorDetail = Collections.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request)));
|
||||
|
@ -81,7 +92,7 @@ public class CommonController extends AbstractErrorController {
|
|||
if (status.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
|
||||
return contentInternalError();
|
||||
} else if (status.equals(HttpStatus.NOT_FOUND)) {
|
||||
return contentNotFround();
|
||||
return contentNotFound();
|
||||
} else {
|
||||
return defaultErrorHandler();
|
||||
}
|
||||
|
@ -93,14 +104,16 @@ public class CommonController extends AbstractErrorController {
|
|||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "/404")
|
||||
public String contentNotFround() {
|
||||
if (!themeService.templateExists(NOT_FOUND_TEMPLATE)) {
|
||||
return defaultErrorHandler();
|
||||
public String contentNotFound() {
|
||||
if (themeService.templateExists(ERROR_TEMPLATE)) {
|
||||
return getActualTemplatePath(ERROR_TEMPLATE);
|
||||
}
|
||||
StrBuilder path = new StrBuilder("themes/");
|
||||
path.append(themeService.getActivatedTheme().getFolderName());
|
||||
path.append("/404");
|
||||
return path.toString();
|
||||
|
||||
if (themeService.templateExists(NOT_FOUND_TEMPLATE)) {
|
||||
return getActualTemplatePath(NOT_FOUND_TEMPLATE);
|
||||
}
|
||||
|
||||
return defaultErrorHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,18 +123,57 @@ public class CommonController extends AbstractErrorController {
|
|||
*/
|
||||
@GetMapping(value = "/500")
|
||||
public String contentInternalError() {
|
||||
if (!themeService.templateExists(INTERNAL_ERROR_TEMPLATE)) {
|
||||
return defaultErrorHandler();
|
||||
if (themeService.templateExists(ERROR_TEMPLATE)) {
|
||||
return getActualTemplatePath(ERROR_TEMPLATE);
|
||||
}
|
||||
|
||||
StrBuilder path = new StrBuilder("themes/");
|
||||
path.append(themeService.getActivatedTheme().getFolderName());
|
||||
path.append("/500");
|
||||
if (themeService.templateExists(INTERNAL_ERROR_TEMPLATE)) {
|
||||
return getActualTemplatePath(INTERNAL_ERROR_TEMPLATE);
|
||||
}
|
||||
|
||||
return defaultErrorHandler();
|
||||
}
|
||||
|
||||
private String defaultErrorHandler() {
|
||||
return DEFAULT_ERROR_PATH;
|
||||
}
|
||||
|
||||
private String getActualTemplatePath(@NonNull String template) {
|
||||
Assert.hasText(template, "FTL template must not be blank");
|
||||
|
||||
StringBuilder path = new StringBuilder();
|
||||
path.append("themes/")
|
||||
.append(themeService.getActivatedTheme().getFolderName())
|
||||
.append('/')
|
||||
.append(FilenameUtils.getBasename(template));
|
||||
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
public String defaultErrorHandler() {
|
||||
return ERROR_TEMPLATE;
|
||||
/**
|
||||
* Handles custom exception, like HaloException.
|
||||
*
|
||||
* @param request http servlet request must not be null
|
||||
*/
|
||||
private void handleCustomException(@NonNull HttpServletRequest request) {
|
||||
Assert.notNull(request, "Http servlet request must not be null");
|
||||
|
||||
Object throwableObject = request.getAttribute("javax.servlet.error.exception");
|
||||
if (throwableObject == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Throwable throwable = (Throwable) throwableObject;
|
||||
|
||||
if (throwable instanceof NestedServletException) {
|
||||
Throwable rootCause = ((NestedServletException) throwable).getRootCause();
|
||||
if (rootCause instanceof HaloException) {
|
||||
HaloException haloException = (HaloException) rootCause;
|
||||
request.setAttribute("javax.servlet.error.status_code", haloException.getStatus().value());
|
||||
request.setAttribute("javax.servlet.error.exception", rootCause);
|
||||
request.setAttribute("javax.servlet.error.message", haloException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue