From b17dbfd2683a3080513bc1b60d7574a640473a13 Mon Sep 17 00:00:00 2001 From: Tuong Nhat Hoang Date: Wed, 4 Sep 2024 22:01:28 +0700 Subject: [PATCH] BE: Make it possible to hide stacktraces in HTTP responses #536 --- .../GlobalErrorWebExceptionHandler.java | 20 +++++++++++++++---- api/src/main/resources/application-local.yml | 5 +++++ api/src/main/resources/application.yml | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/io/kafbat/ui/exception/GlobalErrorWebExceptionHandler.java b/api/src/main/java/io/kafbat/ui/exception/GlobalErrorWebExceptionHandler.java index b4c978ac2..041eafbaf 100644 --- a/api/src/main/java/io/kafbat/ui/exception/GlobalErrorWebExceptionHandler.java +++ b/api/src/main/java/io/kafbat/ui/exception/GlobalErrorWebExceptionHandler.java @@ -10,6 +10,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; import org.springframework.boot.web.reactive.error.ErrorAttributes; @@ -35,6 +36,9 @@ @Order(Ordered.HIGHEST_PRECEDENCE) public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + @Value("${web.exception.include.stacktrace}") + private boolean includeStacktraceInException; + public GlobalErrorWebExceptionHandler(ErrorAttributes errorAttributes, ApplicationContext applicationContext, ServerCodecConfigurer codecConfigurer) { @@ -74,7 +78,7 @@ private Mono renderDefault(Throwable throwable, ServerRequest re .message(coalesce(throwable.getMessage(), "Unexpected internal error")) .requestId(requestId(request)) .timestamp(currentTimestamp()) - .stackTrace(Throwables.getStackTraceAsString(throwable)); + .stackTrace(getStackTrace(throwable)); return ServerResponse .status(ErrorCode.UNEXPECTED.httpStatus()) .contentType(MediaType.APPLICATION_JSON) @@ -88,7 +92,7 @@ private Mono render(CustomBaseException baseException, ServerReq .message(coalesce(baseException.getMessage(), "Internal error")) .requestId(requestId(request)) .timestamp(currentTimestamp()) - .stackTrace(Throwables.getStackTraceAsString(baseException)); + .stackTrace(getStackTrace(baseException)); return ServerResponse .status(errorCode.httpStatus()) .contentType(MediaType.APPLICATION_JSON) @@ -118,7 +122,7 @@ private Mono render(WebExchangeBindException exception, ServerRe .requestId(requestId(request)) .timestamp(currentTimestamp()) .fieldsErrors(fieldsErrors) - .stackTrace(Throwables.getStackTraceAsString(exception)); + .stackTrace(getStackTrace(exception)); return ServerResponse .status(HttpStatus.BAD_REQUEST) .contentType(MediaType.APPLICATION_JSON) @@ -132,13 +136,21 @@ private Mono render(ResponseStatusException exception, ServerReq .message(msg) .requestId(requestId(request)) .timestamp(currentTimestamp()) - .stackTrace(Throwables.getStackTraceAsString(exception)); + .stackTrace(getStackTrace(exception)); return ServerResponse .status(exception.getStatusCode()) .contentType(MediaType.APPLICATION_JSON) .bodyValue(response); } + private String getStackTrace(Throwable exception) { + if (!includeStacktraceInException) { + return ""; + } + + return Throwables.getStackTraceAsString(exception); + } + private String requestId(ServerRequest request) { return request.exchange().getRequest().getId(); } diff --git a/api/src/main/resources/application-local.yml b/api/src/main/resources/application-local.yml index 0c40ff079..4fff370fd 100644 --- a/api/src/main/resources/application-local.yml +++ b/api/src/main/resources/application-local.yml @@ -147,3 +147,8 @@ rbac: - resource: audit actions: all + +web: + exception: + include: + stacktrace: true diff --git a/api/src/main/resources/application.yml b/api/src/main/resources/application.yml index ba26c1f9c..907319c9a 100644 --- a/api/src/main/resources/application.yml +++ b/api/src/main/resources/application.yml @@ -19,3 +19,7 @@ logging: reactor.netty.http.server.AccessLog: INFO org.hibernate.validator: WARN +web: + exception: + include: + stacktrace: false