GlobalRestControllerExceptionHandler.java

1
package org.cardanofoundation.explorer.api.controller.advice;
2
3
import java.util.Arrays;
4
import java.util.Objects;
5
6
import jakarta.validation.ConstraintViolation;
7
import jakarta.validation.ConstraintViolationException;
8
9
import lombok.extern.log4j.Log4j2;
10
11
import org.springframework.http.HttpStatus;
12
import org.springframework.http.ResponseEntity;
13
import org.springframework.validation.FieldError;
14
import org.springframework.web.bind.MethodArgumentNotValidException;
15
import org.springframework.web.bind.annotation.ExceptionHandler;
16
import org.springframework.web.bind.annotation.RestControllerAdvice;
17
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
18
19
import org.apache.logging.log4j.util.Strings;
20
21
import org.cardanofoundation.explorer.api.exception.FetchRewardException;
22
import org.cardanofoundation.explorer.api.exception.NoContentException;
23
import org.cardanofoundation.explorer.api.exception.UnauthorizedException;
24
import org.cardanofoundation.explorer.api.model.response.BaseFilterResponse;
25
import org.cardanofoundation.explorer.common.exception.AccessTokenExpireException;
26
import org.cardanofoundation.explorer.common.exception.BusinessException;
27
import org.cardanofoundation.explorer.common.exception.CommonErrorCode;
28
import org.cardanofoundation.explorer.common.exception.ErrorResponse;
29
import org.cardanofoundation.explorer.common.exception.IgnoreRollbackException;
30
import org.cardanofoundation.explorer.common.exception.InvalidAccessTokenException;
31
import org.cardanofoundation.explorer.common.exception.TokenRefreshException;
32
33
@Log4j2
34
@RestControllerAdvice
35
public class GlobalRestControllerExceptionHandler {
36
37
  @ExceptionHandler(MethodArgumentNotValidException.class)
38
  public ResponseEntity<ErrorResponse> handleValidationExceptions(
39
      MethodArgumentNotValidException ex) {
40
    FieldError fieldError = ex.getBindingResult().getFieldError();
41
    String errorMessage = "Invalid parameter";
42 1 1. handleValidationExceptions : negated conditional → NO_COVERAGE
    if (Objects.nonNull(fieldError)) {
43
      errorMessage = fieldError.getDefaultMessage();
44
    }
45 1 1. handleValidationExceptions : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleValidationExceptions → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
46
        .body(
47
            ErrorResponse.builder()
48
                .errorCode(CommonErrorCode.INVALID_PARAM.getCode())
49
                .errorMessage(errorMessage)
50
                .build());
51
  }
52
53
  @ExceptionHandler({BusinessException.class})
54
  public ResponseEntity<ErrorResponse> handleException(BusinessException e) {
55
    log.warn("Business logic exception: {}, stack trace: {}", e.getMessage(), e.getErrorMsg());
56 1 1. handleException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
57
        .body(
58
            ErrorResponse.builder()
59
                .errorCode(e.getErrorCode())
60
                .errorMessage(e.getErrorMsg())
61
                .build());
62
  }
63
64
  @ExceptionHandler({FetchRewardException.class})
65
  public ResponseEntity<ErrorResponse> handleException(FetchRewardException e) {
66
    log.warn("Business logic exception: {}, stack trace: {}", e.getMessage(), e.getErrorMsg());
67 1 1. handleException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
68
        .body(
69
            ErrorResponse.builder()
70
                .errorCode(e.getErrorCode())
71
                .errorMessage(e.getErrorMsg())
72
                .build());
73
  }
74
75
  @ExceptionHandler({IgnoreRollbackException.class})
76
  public ResponseEntity<ErrorResponse> handleException(IgnoreRollbackException e) {
77
    log.warn("No rollback exception: {}, stack trace:", e.getMessage());
78 1 1. handleException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
79
        .body(
80
            ErrorResponse.builder()
81
                .errorCode(e.getErrorCode())
82
                .errorMessage(e.getErrorMsg())
83
                .build());
84
  }
85
86
  @ExceptionHandler({Exception.class})
87
  public ResponseEntity<ErrorResponse> handleException(Exception e) {
88
    log.warn("Unknown exception: {}, stack trace:", e.getMessage(), e);
89 1 1. handleException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE
    return new ResponseEntity<>(
90
        ErrorResponse.builder()
91
            .errorCode(CommonErrorCode.UNKNOWN_ERROR.getServiceErrorCode())
92
            .errorMessage(CommonErrorCode.UNKNOWN_ERROR.getDesc())
93
            .build(),
94
        HttpStatus.INTERNAL_SERVER_ERROR);
95
  }
96
97
  @ExceptionHandler({TokenRefreshException.class})
98
  public ResponseEntity<ErrorResponse> handleAuthException(TokenRefreshException e) {
99
    log.warn("Refresh token exception: {}, stack trace:", e.getMessage());
100 1 1. handleAuthException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
101
        .body(
102
            ErrorResponse.builder()
103
                .errorCode(e.getErrorCode().getServiceErrorCode())
104
                .errorMessage(e.getErrorCode().getDesc())
105
                .build());
106
  }
107
108
  @ExceptionHandler({AccessTokenExpireException.class})
109
  public ResponseEntity<ErrorResponse> handleAuthException(AccessTokenExpireException e) {
110
    log.warn("Access token expired: {}, stack trace:", e.getMessage());
111 1 1. handleAuthException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
112
        .body(
113
            ErrorResponse.builder()
114
                .errorCode(e.getErrorCode().getServiceErrorCode())
115
                .errorMessage(e.getErrorCode().getDesc())
116
                .build());
117
  }
118
119
  @ExceptionHandler({InvalidAccessTokenException.class})
120
  public ResponseEntity<ErrorResponse> handleAuthException(InvalidAccessTokenException e) {
121
    log.warn("Invalid access token: {}", e.getErrorCode());
122 1 1. handleAuthException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
123
        .body(
124
            ErrorResponse.builder()
125
                .errorCode(e.getErrorCode().getServiceErrorCode())
126
                .errorMessage(e.getErrorCode().getDesc())
127
                .build());
128
  }
129
130
  @ExceptionHandler({NoContentException.class})
131
  public ResponseEntity<BaseFilterResponse<?>> handleNoContent(NoContentException e) {
132 1 1. handleNoContent : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleNoContent → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.OK).body(new BaseFilterResponse<>());
133
  }
134
135
  @ExceptionHandler({ConstraintViolationException.class})
136
  public ResponseEntity<ErrorResponse> handleConstraintViolationException(
137
      ConstraintViolationException e) {
138
    log.warn("constraint not valid: {}", e.getMessage());
139
140
    String[] errors =
141
        e.getConstraintViolations().stream()
142
            .map(ConstraintViolation::getMessage)
143
            .filter(Strings::isNotBlank)
144 1 1. lambda$handleConstraintViolationException$0 : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::lambda$handleConstraintViolationException$0 → NO_COVERAGE
            .toArray(String[]::new);
145
146 1 1. handleConstraintViolationException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleConstraintViolationException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
147
        .body(
148
            ErrorResponse.builder()
149
                .errorCode(String.valueOf(HttpStatus.BAD_REQUEST.value()))
150
                .errorMessage(Arrays.toString(errors))
151
                .build());
152
  }
153
154
  @ExceptionHandler({IllegalArgumentException.class})
155
  public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException e) {
156
    log.warn("argument not valid: {}", e.getMessage());
157
158 1 1. handleIllegalArgumentException : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleIllegalArgumentException → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
159
        .body(
160
            ErrorResponse.builder()
161
                .errorCode(String.valueOf(HttpStatus.BAD_REQUEST.value()))
162
                .errorMessage(e.getMessage())
163
                .build());
164
  }
165
166
  @ExceptionHandler({MethodArgumentTypeMismatchException.class})
167
  public ResponseEntity<ErrorResponse> handleMethodArgumentTypeMismatch(
168
      MethodArgumentTypeMismatchException e) {
169
    log.warn("Argument type not valid: {}", e.getMessage());
170
171 1 1. handleMethodArgumentTypeMismatch : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleMethodArgumentTypeMismatch → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
172
        .body(
173
            ErrorResponse.builder()
174
                .errorCode(String.valueOf(HttpStatus.BAD_REQUEST.value()))
175
                .errorMessage(e.getName() + " not valid")
176
                .build());
177
  }
178
179
  @ExceptionHandler({UnauthorizedException.class})
180
  public ResponseEntity<ErrorResponse> handleMethodArgumentTypeMismatch(UnauthorizedException e) {
181 1 1. handleMethodArgumentTypeMismatch : replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleMethodArgumentTypeMismatch → NO_COVERAGE
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
182
        .body(
183
            ErrorResponse.builder()
184
                .errorCode(e.getErrorCode().getServiceErrorCode())
185
                .errorMessage(e.getErrorCode().getDesc())
186
                .build());
187
  }
188
}

Mutations

42

1.1
Location : handleValidationExceptions
Killed by : none
negated conditional → NO_COVERAGE

45

1.1
Location : handleValidationExceptions
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleValidationExceptions → NO_COVERAGE

56

1.1
Location : handleException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE

67

1.1
Location : handleException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE

78

1.1
Location : handleException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE

89

1.1
Location : handleException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleException → NO_COVERAGE

100

1.1
Location : handleAuthException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE

111

1.1
Location : handleAuthException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE

122

1.1
Location : handleAuthException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleAuthException → NO_COVERAGE

132

1.1
Location : handleNoContent
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleNoContent → NO_COVERAGE

144

1.1
Location : lambda$handleConstraintViolationException$0
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::lambda$handleConstraintViolationException$0 → NO_COVERAGE

146

1.1
Location : handleConstraintViolationException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleConstraintViolationException → NO_COVERAGE

158

1.1
Location : handleIllegalArgumentException
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleIllegalArgumentException → NO_COVERAGE

171

1.1
Location : handleMethodArgumentTypeMismatch
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleMethodArgumentTypeMismatch → NO_COVERAGE

181

1.1
Location : handleMethodArgumentTypeMismatch
Killed by : none
replaced return value with null for org/cardanofoundation/explorer/api/controller/advice/GlobalRestControllerExceptionHandler::handleMethodArgumentTypeMismatch → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.14.2