Closed robozb closed 1 year ago
the mvn spring-boot:run
has a context in spring-boot-maven-plugin maybe, but java -jar
not need. Something maybe can be found out from the context.
I think this is due to devtools setting properties as explained here: https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools.property-defaults (in this case ˋ server.error.*ˋ).
This behavior is disabled when running in jar mode as documented.
@robozb you have devtools on the classpath, which configures settings for local devlopment. Devtools is not enabled when you start the app as a production app.
Going forward, please ask questions on StackOverflow as this issue tracker is not meant for this. If you want to report an issue, your dependency tree and a video are not the right information to share with us. Rather a minimal sample that we can use to reproduce the issue.
@robozb you have devtools on the classpath, which configures settings for local devlopment. Devtools is not enabled when you start the app as a production app.
Going forward, please ask questions on StackOverflow as this issue tracker is not meant for this. If you want to report an issue, your dependency tree and a video are not the right information to share with us. Rather a minimal sample that we can use to reproduce the issue.
Dear @snicoll,
Thank you so much for your kind, quick answer!
OK, I understand I'll do so in the future!
Have a nice day!
Bela
I think this is due to devtools setting properties as explained here: https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools.property-defaults (in this case ˋ server.error.*ˋ).
This behavior is disabled when running in jar mode as documented.
Dear @bclozel,
OH, great I'm getting understand! Thank you for your time!
Best regards
Bela
Thank you so much, I could solve the problem with: @ControllerAdvice
, @ExceptionHandler
and a CustomErrorResponse
class:
An example implementation:
import jakarta.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.LocalDateTime;
import lombok.Data;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<CustomErrorResponse> handleException(Exception ex, HttpServletRequest request) {
Class clazz = ex.getClass();
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
if (clazz.isAnnotationPresent(ResponseStatus.class)) {
ResponseStatus annotation = (ResponseStatus) clazz.getAnnotation(ResponseStatus.class);
status = annotation.value();
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
String stackTrace = sw.toString();
CustomErrorResponse errorResponse = new CustomErrorResponse(
status.value(),
status.getReasonPhrase(),
stackTrace,
ex.getMessage(),
request.getRequestURI()
);
return new ResponseEntity<>(errorResponse, status);
}
@Data
public static class CustomErrorResponse {
private LocalDateTime timestamp;
private int status;
private String error;
private String trace;
private String message;
private String path;
public CustomErrorResponse(int status, String error, String trace, String message, String path) {
this.timestamp = LocalDateTime.now();
this.status = status;
this.error = error;
this.trace = trace;
this.message = message;
this.path = path;
}
}
}
An Exception example class:
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@NoArgsConstructor
@Getter
public class DetailedError extends Exception {
public DetailedError(String message) {
super(message);
}
public DetailedError(String message, Throwable cause) {
super(message, cause);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@Getter
public static class BadRequest extends DetailedError {
public BadRequest(String message) {
super(message);
}
public BadRequest(String message, Throwable cause) {
super(message, cause);
}
public BadRequest() {
}
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public static class InternalServerError extends DetailedError {
public InternalServerError(String message) {
super(message);
}
public InternalServerError(String message, Throwable cause) {
super(message, cause);
}
public InternalServerError() {
}
}
@ResponseStatus(HttpStatus.NOT_FOUND)
public static class NotFound extends DetailedError {
public NotFound(String message) {
super(message);
}
public NotFound(String message, Throwable cause) {
super(message, cause);
}
public NotFound() {
}
}
}
I don't understand what you're doing. If you want trace, please read the doc I've referenced and set server.error.include-stacktrace=always
in your configuration. No need for custom code.
OK, great, thank you! I thought It depends on the existence of the DevTools! Thanks again!
Dear All,
I don't know why but Spring Boot behaves differently when I package it into a JAR versus when I start it with mvn spring-boot:run.
Spring serializes the same Exception of same Rest method on different way.
Two cases: Run with: mvn spring-boot:run: I see the trace and message fields. Run the JAR with: ...java.exe -jar .\vsm.jar: The "trace and message fields" are dissapeared.
I made a short video about the problem: https://www.youtube.com/watch?v=jv_eQONkyWY&ab_channel=B%C3%A9ciRoboz
Thank you so much for any help or advice!
Kind Regards:
Bela
Dependencies: