diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java index 26084ad077..513aff6891 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java @@ -33,13 +33,13 @@ public class ThingsboardErrorResponse { // Error code private final ThingsboardErrorCode errorCode; - private final Date timestamp; + private final long timestamp; protected ThingsboardErrorResponse(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) { this.message = message; this.errorCode = errorCode; this.status = status; - this.timestamp = new java.util.Date(); + this.timestamp = System.currentTimeMillis(); } public static ThingsboardErrorResponse of(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) { @@ -75,7 +75,7 @@ public class ThingsboardErrorResponse { } @ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY) - public Date getTimestamp() { + public long getTimestamp() { return timestamp; } } diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java index b2509187d5..2e572ce8c4 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java @@ -16,6 +16,8 @@ package org.thingsboard.server.exception; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -28,7 +30,9 @@ import org.springframework.security.authentication.LockedException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.context.request.WebRequest; @@ -43,16 +47,21 @@ import org.thingsboard.server.service.security.exception.JwtExpiredTokenExceptio import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; import org.thingsboard.server.service.security.exception.UserPasswordNotValidException; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Optional; + +import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION; @Slf4j +@Controller @RestControllerAdvice -public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler { +public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler, ErrorController { private static final Map statusToErrorCodeMap = new HashMap<>(); static { @@ -90,6 +99,17 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand return errorCodeToStatusMap.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR); } + @RequestMapping("/error") + public ResponseEntity handleError(HttpServletRequest request) { + HttpStatus httpStatus = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)) + .map(status -> HttpStatus.resolve(Integer.parseInt(status.toString()))) + .orElse(HttpStatus.INTERNAL_SERVER_ERROR); + String errorMessage = Optional.ofNullable(request.getAttribute(ERROR_EXCEPTION)) + .map(e -> (ExceptionUtils.getMessage((Throwable) e))) + .orElse(httpStatus.getReasonPhrase()); + return new ResponseEntity<>(ThingsboardErrorResponse.of(errorMessage, statusToErrorCode(httpStatus), httpStatus), httpStatus); + } + @Override @ExceptionHandler(AccessDeniedException.class) public void handle(HttpServletRequest request, HttpServletResponse response,