2
2
3
3
4
4
import com .patternknife .securityhelper .oauth2 .client .config .response .error .dto .CustomErrorResponsePayload ;
5
- import com .patternknife .securityhelper .oauth2 .client .config .response .error .exception .auth .*;
6
- import com .patternknife .securityhelper .oauth2 .client .config .response .error .exception .data .*;
7
-
8
- import com .patternknife .securityhelper .oauth2 .client .config .response .error .exception .payload .SearchFilterException ;
9
5
10
6
import com .patternknife .securityhelper .oauth2 .client .config .response .error .message .GeneralErrorMessage ;
11
- import jakarta .servlet .http .HttpServletRequest ;
12
- import jakarta .validation .ConstraintViolationException ;
7
+ import io .github .patternknife .securityhelper .oauth2 .api .config .response .error .ExceptionKnifeUtils ;
8
+ import io .github .patternknife .securityhelper .oauth2 .api .config .response .error .dto .ErrorResponsePayload ;
9
+ import io .github .patternknife .securityhelper .oauth2 .api .config .response .error .exception .auth .KnifeOauth2AuthenticationException ;
10
+ import io .github .patternknife .securityhelper .oauth2 .api .config .security .message .DefaultSecurityUserExceptionMessage ;
11
+ import io .github .patternknife .securityhelper .oauth2 .api .config .security .message .ISecurityUserExceptionMessageService ;
12
+ import lombok .RequiredArgsConstructor ;;
13
13
import org .springframework .http .HttpStatus ;
14
14
import org .springframework .http .ResponseEntity ;
15
- import org .springframework .http .converter .HttpMessageNotReadableException ;
16
- import org .springframework .validation .BindException ;
17
- import org .springframework .validation .FieldError ;
18
- import org .springframework .web .bind .MethodArgumentNotValidException ;
19
- import org .springframework .web .bind .MissingServletRequestParameterException ;
15
+ import org .springframework .security .access .AccessDeniedException ;
16
+ import org .springframework .security .core .AuthenticationException ;
20
17
import org .springframework .web .bind .annotation .ControllerAdvice ;
21
18
import org .springframework .web .bind .annotation .ExceptionHandler ;
22
- import org .springframework .web .client .ResourceAccessException ;
23
- import org .springframework .web .context .request .WebRequest ;
24
19
25
- import java .util .HashMap ;
26
- import java .util .Map ;
20
+ import org .springframework .web .context .request .WebRequest ;
27
21
28
22
23
+ /*
24
+ *
25
+ * Customize the exception payload by implementing this, which replaces
26
+ * 'io.github.patternknife.securityhelper.oauth2.api.config.response.error.SecurityKnifeExceptionHandler'
27
+ *
28
+ * Once you create 'GlobalExceptionHandler', you should insert the following two as default. Otherwise, 'unhandledExceptionHandler' is prior to 'io.github.patternknife.securityhelper.oauth2.api.config.response.error.SecurityKnifeExceptionHandler'.
29
+ *
30
+ * */
29
31
@ ControllerAdvice
32
+ @ RequiredArgsConstructor
30
33
public class GlobalExceptionHandler {
31
34
32
-
33
- // UserDeletedException : caused by the process of user deactivation
34
- // UserRestoredException : caused by the process of user reactivation
35
- @ ExceptionHandler ({UserDeletedException .class , UserRestoredException .class })
36
- public ResponseEntity <?> activationException (Exception ex , WebRequest request ) {
37
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage () != null ? ex .getMessage () : CustomExceptionUtils .getAllCauses (ex ),
38
- request .getDescription (false ),ex .getMessage () , ex .getStackTrace ()[0 ].toString ());
39
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .FORBIDDEN );
40
- }
41
-
42
-
43
- // 2. data
44
- @ ExceptionHandler (ResourceNotFoundException .class )
45
- public ResponseEntity <?> resourceNotFoundException (ResourceNotFoundException ex , WebRequest request ) {
46
-
47
- CustomErrorResponsePayload customErrorResponsePayload ;
48
- if (ex .getErrorMessages () != null ){
49
-
50
- customErrorResponsePayload = new CustomErrorResponsePayload (ex .getErrorMessages (),
51
- ex , request .getDescription (false ), CustomExceptionUtils .getAllStackTraces (ex ),
52
- CustomExceptionUtils .getAllCauses (ex ), null );
53
-
54
- }else {
55
- customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
56
- ex .getMessage (), CustomExceptionUtils .getAllStackTraces (ex ),
57
- CustomExceptionUtils .getAllCauses (ex ));
35
+ private final ISecurityUserExceptionMessageService iSecurityUserExceptionMessageService ;
36
+
37
+ // 401 : Authentication
38
+ @ ExceptionHandler ({AuthenticationException .class })
39
+ public ResponseEntity <?> authenticationException (Exception ex , WebRequest request ) {
40
+ ErrorResponsePayload errorResponsePayload ;
41
+ if (ex instanceof KnifeOauth2AuthenticationException && ((KnifeOauth2AuthenticationException ) ex ).getErrorMessages () != null ) {
42
+ errorResponsePayload = new ErrorResponsePayload (((KnifeOauth2AuthenticationException ) ex ).getErrorMessages (),
43
+ ex , request .getDescription (false ), ExceptionKnifeUtils .getAllStackTraces (ex ),
44
+ ExceptionKnifeUtils .getAllCauses (ex ), null );
45
+ }else {
46
+ errorResponsePayload = new ErrorResponsePayload (ExceptionKnifeUtils .getAllCauses (ex ), request .getDescription (false ), iSecurityUserExceptionMessageService .getUserMessage (DefaultSecurityUserExceptionMessage .AUTHENTICATION_LOGIN_FAILURE ),
47
+ ex .getMessage (), ex .getStackTrace ()[0 ].toString ());
58
48
}
59
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .NOT_FOUND );
60
-
61
- }
62
-
63
-
64
-
65
- @ ExceptionHandler (SearchFilterException .class )
66
- public ResponseEntity <?> searchFilterException (SearchFilterException ex , WebRequest request ) {
67
-
68
- //logger.error(ex.getMessage());
69
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getCause ().getMessage (), request .getDescription (false ),
70
- ex .getMessage (), ex .getStackTrace ()[0 ].toString ());
71
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .BAD_REQUEST );
49
+ return new ResponseEntity <>(errorResponsePayload , HttpStatus .UNAUTHORIZED );
72
50
}
73
51
74
-
75
-
76
- @ ExceptionHandler (NullPointerException .class )
77
- public ResponseEntity <?> nullPointerException (NullPointerException ex , WebRequest request ) {
78
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
79
- GeneralErrorMessage .NULL_VALUE_FOUND .getUserMessage (), CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
80
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .NOT_FOUND );
52
+ // 403 : Authorization
53
+ @ ExceptionHandler ({ AccessDeniedException .class })
54
+ public ResponseEntity <?> authorizationException (Exception ex , WebRequest request ) {
55
+ ErrorResponsePayload errorResponsePayload = new ErrorResponsePayload (ex .getMessage () != null ? ex .getMessage () : ExceptionKnifeUtils .getAllCauses (ex ), request .getDescription (false ),
56
+ ex .getMessage () == null || ex .getMessage ().equals ("Access Denied" ) ? iSecurityUserExceptionMessageService .getUserMessage (DefaultSecurityUserExceptionMessage .AUTHORIZATION_FAILURE ) : ex .getMessage (), ex .getStackTrace ()[0 ].toString ());
57
+ return new ResponseEntity <>(errorResponsePayload , HttpStatus .FORBIDDEN );
81
58
}
82
-
83
-
84
-
85
-
86
-
87
- // 3. Request @Valid
88
- /* 1. Validating the request body (when not using @RequestParam): Error thrown by @Valid. */
89
- @ ExceptionHandler (MethodArgumentNotValidException .class )
90
- public ResponseEntity <?> methodArgumentNotValidException (MethodArgumentNotValidException ex , WebRequest request ) {
91
-
92
- Map <String , String > userValidationMessages = CustomExceptionUtils .extractMethodArgumentNotValidErrors (ex );
93
-
94
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
95
- null ,
96
- userValidationMessages ,
97
- CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
98
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
99
- }
100
- //
101
- //The types of individual parameters in the request body (String, Date, Integer) are different, or there is a JSON format error.
102
- @ ExceptionHandler (HttpMessageNotReadableException .class )
103
- public ResponseEntity <?> httpMessageNotReadableExceptionHandler (HttpMessageNotReadableException ex , WebRequest request ) {
104
-
105
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
106
- "The received form does not match. Please contact the administrator with the following information. (Error details: " + ex .getMostSpecificCause ().getMessage () + ")" ,
107
- null ,
108
- CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
109
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .BAD_REQUEST );
110
- }
111
-
112
- /* 2-1. In the case of @RequestParam: Validity check thrown by @Validated. */
113
- @ ExceptionHandler (ConstraintViolationException .class )
114
- public ResponseEntity <?> missingServletRequestParameterException (ConstraintViolationException ex , WebRequest request , HttpServletRequest h ) {
115
-
116
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
117
- ex .getMessage (), CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
118
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
119
- }
120
- /* 2-2. In the case of @RequestParam: The error thrown when @RequestParam is completely missing in the Controller. */
121
- @ ExceptionHandler (MissingServletRequestParameterException .class )
122
- public ResponseEntity <?> missingServletRequestParameterException (MissingServletRequestParameterException ex , WebRequest request , HttpServletRequest h ) {
123
-
124
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
125
- "Required parameter (" + ex .getParameterName () + ") is missing." , CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
126
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
127
- }
128
-
129
- /* 3. Other Custom Validation: For example, search in the source with @ValidPart. */
130
- @ ExceptionHandler (BindException .class )
131
- public ResponseEntity <?> bindExceptionHandler (BindException ex , WebRequest request ) {
132
-
133
- Map <String , String > errorMessages = new HashMap <>();
134
-
135
- for (FieldError fieldError : ex .getBindingResult ().getFieldErrors ()) {
136
- errorMessages .put (fieldError .getField (), fieldError .getDefaultMessage ());
137
- }
138
-
139
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ), null ,
140
- errorMessages ,
141
- CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
142
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
143
- }
144
-
145
-
146
- // 4. Custom Validation using DB(select)
147
-
148
- @ ExceptionHandler (AlreadyExistsException .class )
149
- public ResponseEntity <?> alreadyExistsException (AlreadyExistsException ex , WebRequest request ) {
150
-
151
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
152
- ex .getMessage (), CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
153
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
154
- }
155
-
156
- @ ExceptionHandler (IllegalStateException .class )
157
- public ResponseEntity <?> illegalStateException (IllegalStateException ex , WebRequest request ) {
158
-
159
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
160
- ex .getMessage (), CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
161
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .BAD_REQUEST );
162
- }
163
-
164
-
165
- @ ExceptionHandler (AlreadyInProgressException .class )
166
- public ResponseEntity <?> alreadyInProgressException (AlreadyInProgressException ex , WebRequest request ) {
167
-
168
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
169
- ex .getMessage (), CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
170
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .UNPROCESSABLE_ENTITY );
171
- }
172
-
173
-
174
- // config/resttemplate
175
- @ ExceptionHandler (ResourceAccessException .class )
176
- public ResponseEntity <?> restTemplateAccessException (ResourceAccessException ex , WebRequest request ) {
177
-
178
- CustomErrorResponsePayload customErrorResponsePayload = new CustomErrorResponsePayload (ex .getMessage (), request .getDescription (false ),
179
- "We apologize for the inconvenience. The call to the 3rd Party API provider has failed. If the problem persists, please contact customer service." , CustomExceptionUtils .getAllStackTraces (ex ), CustomExceptionUtils .getAllCauses (ex ));
180
- return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .REQUEST_TIMEOUT );
181
- }
182
-
183
59
184
60
// Unhandled
185
61
@ ExceptionHandler (Exception .class )
@@ -189,6 +65,4 @@ public ResponseEntity<?> unhandledExceptionHandler(Exception ex, WebRequest requ
189
65
return new ResponseEntity <>(customErrorResponsePayload , HttpStatus .INTERNAL_SERVER_ERROR );
190
66
}
191
67
192
-
193
-
194
68
}
0 commit comments