mirror of https://github.com/halo-dev/halo
refactor: optimize the exception information (#3747)
#### What type of PR is this? /kind improvement /area core #### What this PR does / why we need it: 优化异常信息 - 5xx 服务器内部错误不显示异常详情到页面,如主题模板表达式错误 - 访问 `GET /apis/api.halo.run/v1alpha1/comments` 提示 400 且不会打印异常堆栈 - 访问不存在的主题静态资源提示 404 且不会打印异常堆栈,如 `GET /themes/guqing-higan/assets/dist/style1.css` #### Which issue(s) this PR fixes: Fixes #3483 #### Does this PR introduce a user-facing change? ```release-note None ```pull/3792/head
parent
a94c0c7f85
commit
5477e30781
|
@ -8,6 +8,7 @@ import java.time.Instant;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
||||||
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
|
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
|
||||||
import org.springframework.boot.web.reactive.error.ErrorAttributes;
|
import org.springframework.boot.web.reactive.error.ErrorAttributes;
|
||||||
|
@ -39,7 +40,7 @@ public class ProblemDetailErrorAttributes implements ErrorAttributes {
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getErrorAttributes(ServerRequest request,
|
public Map<String, Object> getErrorAttributes(ServerRequest request,
|
||||||
ErrorAttributeOptions options) {
|
ErrorAttributeOptions options) {
|
||||||
var errAttributes = new LinkedHashMap<String, Object>();
|
final var errAttributes = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
var error = getError(request);
|
var error = getError(request);
|
||||||
var responseStatusAnno = from(error.getClass(), SearchStrategy.TYPE_HIERARCHY)
|
var responseStatusAnno = from(error.getClass(), SearchStrategy.TYPE_HIERARCHY)
|
||||||
|
@ -50,8 +51,12 @@ public class ProblemDetailErrorAttributes implements ErrorAttributes {
|
||||||
if (error instanceof ErrorResponse er) {
|
if (error instanceof ErrorResponse er) {
|
||||||
errorResponse = er;
|
errorResponse = er;
|
||||||
} else {
|
} else {
|
||||||
var reason = responseStatusAnno.getValue("reason", String.class)
|
var reason = Optional.of(status)
|
||||||
.orElse(error.getMessage());
|
.filter(HttpStatusCode::is5xxServerError)
|
||||||
|
.map(s -> "Something went wrong, please try again later.")
|
||||||
|
.orElseGet(() -> responseStatusAnno.getValue("reason", String.class)
|
||||||
|
.orElse(error.getMessage())
|
||||||
|
);
|
||||||
errorResponse = ErrorResponse.create(error, status, reason);
|
errorResponse = ErrorResponse.create(error, status, reason);
|
||||||
}
|
}
|
||||||
var problemDetail =
|
var problemDetail =
|
||||||
|
|
|
@ -46,6 +46,9 @@ public class ThemeConfiguration {
|
||||||
var resource = request.pathVariable("resource");
|
var resource = request.pathVariable("resource");
|
||||||
resource = StringUtils.removeStart(resource, "/");
|
resource = StringUtils.removeStart(resource, "/");
|
||||||
var fsRes = new FileSystemResource(getThemeAssetsPath(themeName, resource));
|
var fsRes = new FileSystemResource(getThemeAssetsPath(themeName, resource));
|
||||||
|
if (!fsRes.exists()) {
|
||||||
|
return ServerResponse.notFound().build();
|
||||||
|
}
|
||||||
var bodyBuilder = ServerResponse.ok()
|
var bodyBuilder = ServerResponse.ok()
|
||||||
.cacheControl(cacheProperties.getCachecontrol().toHttpCacheControl());
|
.cacheControl(cacheProperties.getCachecontrol().toHttpCacheControl());
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
import org.springframework.web.server.ServerWebInputException;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.core.scheduler.Schedulers;
|
import reactor.core.scheduler.Schedulers;
|
||||||
import run.halo.app.content.comment.CommentRequest;
|
import run.halo.app.content.comment.CommentRequest;
|
||||||
|
@ -230,7 +231,7 @@ public class CommentFinderEndpoint implements CustomEndpoint {
|
||||||
public String getKind() {
|
public String getKind() {
|
||||||
String kind = emptyToNull(queryParams.getFirst("kind"));
|
String kind = emptyToNull(queryParams.getFirst("kind"));
|
||||||
if (kind == null) {
|
if (kind == null) {
|
||||||
throw new IllegalArgumentException("The kind must not be null.");
|
throw new ServerWebInputException("The kind must not be null.");
|
||||||
}
|
}
|
||||||
return kind;
|
return kind;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +245,7 @@ public class CommentFinderEndpoint implements CustomEndpoint {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
String name = emptyToNull(queryParams.getFirst("name"));
|
String name = emptyToNull(queryParams.getFirst("name"));
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new IllegalArgumentException("The name must not be null.");
|
throw new ServerWebInputException("The name must not be null.");
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,13 +105,14 @@ class I18nExceptionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldGetErrorIfThrowingGeneralException() {
|
void shouldGetErrorIfThrowingGeneralException() {
|
||||||
|
// problem reason will be a fixed prompt when internal server error occurred.
|
||||||
webClient.get().uri("/response-entity/general-error")
|
webClient.get().uri("/response-entity/general-error")
|
||||||
.exchange()
|
.exchange()
|
||||||
.expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
|
.expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
.expectBody(ProblemDetail.class)
|
.expectBody(ProblemDetail.class)
|
||||||
.value(problemDetail -> {
|
.value(problemDetail -> {
|
||||||
assertEquals("Internal Server Error", problemDetail.getTitle());
|
assertEquals("Internal Server Error", problemDetail.getTitle());
|
||||||
assertEquals("Something went wrong",
|
assertEquals("Something went wrong, please try again later.",
|
||||||
problemDetail.getDetail());
|
problemDetail.getDetail());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue