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
guqing 2023-04-19 18:26:24 +08:00 committed by GitHub
parent a94c0c7f85
commit 5477e30781
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 6 deletions

View File

@ -8,6 +8,7 @@ import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
@ -39,7 +40,7 @@ public class ProblemDetailErrorAttributes implements ErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request,
ErrorAttributeOptions options) {
var errAttributes = new LinkedHashMap<String, Object>();
final var errAttributes = new LinkedHashMap<String, Object>();
var error = getError(request);
var responseStatusAnno = from(error.getClass(), SearchStrategy.TYPE_HIERARCHY)
@ -50,8 +51,12 @@ public class ProblemDetailErrorAttributes implements ErrorAttributes {
if (error instanceof ErrorResponse er) {
errorResponse = er;
} else {
var reason = responseStatusAnno.getValue("reason", String.class)
.orElse(error.getMessage());
var reason = Optional.of(status)
.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);
}
var problemDetail =

View File

@ -46,6 +46,9 @@ public class ThemeConfiguration {
var resource = request.pathVariable("resource");
resource = StringUtils.removeStart(resource, "/");
var fsRes = new FileSystemResource(getThemeAssetsPath(themeName, resource));
if (!fsRes.exists()) {
return ServerResponse.notFound().build();
}
var bodyBuilder = ServerResponse.ok()
.cacheControl(cacheProperties.getCachecontrol().toHttpCacheControl());
try {

View File

@ -22,6 +22,7 @@ import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebInputException;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import run.halo.app.content.comment.CommentRequest;
@ -230,7 +231,7 @@ public class CommentFinderEndpoint implements CustomEndpoint {
public String getKind() {
String kind = emptyToNull(queryParams.getFirst("kind"));
if (kind == null) {
throw new IllegalArgumentException("The kind must not be null.");
throw new ServerWebInputException("The kind must not be null.");
}
return kind;
}
@ -244,7 +245,7 @@ public class CommentFinderEndpoint implements CustomEndpoint {
public String getName() {
String name = emptyToNull(queryParams.getFirst("name"));
if (name == null) {
throw new IllegalArgumentException("The name must not be null.");
throw new ServerWebInputException("The name must not be null.");
}
return name;
}

View File

@ -105,13 +105,14 @@ class I18nExceptionTest {
@Test
void shouldGetErrorIfThrowingGeneralException() {
// problem reason will be a fixed prompt when internal server error occurred.
webClient.get().uri("/response-entity/general-error")
.exchange()
.expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
.expectBody(ProblemDetail.class)
.value(problemDetail -> {
assertEquals("Internal Server Error", problemDetail.getTitle());
assertEquals("Something went wrong",
assertEquals("Something went wrong, please try again later.",
problemDetail.getDetail());
});
}