-
-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BE: Make it possible to hide stacktraces in HTTP responses #536 #537
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<ServerResponse> 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<ServerResponse> 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<ServerResponse> 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<ServerResponse> 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 ""; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A dummy value like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, look much better! |
||
} | ||
|
||
return Throwables.getStackTraceAsString(exception); | ||
} | ||
|
||
private String requestId(ServerRequest request) { | ||
return request.exchange().getRequest().getId(); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,3 +147,8 @@ rbac: | |
|
||
- resource: audit | ||
actions: all | ||
|
||
web: | ||
exception: | ||
include: | ||
stacktrace: true |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,3 +19,7 @@ logging: | |
reactor.netty.http.server.AccessLog: INFO | ||
org.hibernate.validator: WARN | ||
|
||
web: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than setting it to false here, let's define a default state for the property: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, look much better! |
||
exception: | ||
include: | ||
stacktrace: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also add this property into our contracts, so it could be changed in UI via wizard?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you hind me where to put the config on.
I saw that DynamicConfigOperations load config from DYNAMIC_CONFIG_PATH_ENV_PROPERTY which will be overridden on each configuration submission through UI wizard.
And from README I saw that can enable the dynamic through DYNAMIC_CONFIG_ENABLED: 'true' on docker compose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @Haarolean, could you help me with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can put it temporarily wherever you wish for testing purposes, I like to put mine into
/tmp
.You have to pass it separately as an arg, like mentioned here:
docker run -it -p 8080:8080 -e spring.config.additional-location=/tmp/config.yml -v /tmp/kui/config.yml:/tmp/config.yml ghcr.io/kafbat/kafka-ui
(or an equivalent for a jar file).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I will try it out