70
70
* using view resolution (e.g., via {@code ContentNegotiatingViewResolver}),
71
71
* then {@code DefaultHandlerExceptionResolver} is good enough.
72
72
*
73
- * <p>Note that in order for an {@code @ControllerAdvice} sub-class to be
73
+ * <p>Note that in order for an {@code @ControllerAdvice} subclass to be
74
74
* detected, {@link ExceptionHandlerExceptionResolver} must be configured.
75
75
*
76
76
* @author Rossen Stoyanchev
@@ -121,8 +121,9 @@ public abstract class ResponseEntityExceptionHandler {
121
121
AsyncRequestTimeoutException .class
122
122
})
123
123
@ Nullable
124
- public final ResponseEntity <Object > handleException (Exception ex , WebRequest request ) {
124
+ public final ResponseEntity <Object > handleException (Exception ex , WebRequest request ) throws Exception {
125
125
HttpHeaders headers = new HttpHeaders ();
126
+
126
127
if (ex instanceof HttpRequestMethodNotSupportedException ) {
127
128
HttpStatus status = HttpStatus .METHOD_NOT_ALLOWED ;
128
129
return handleHttpRequestMethodNotSupported ((HttpRequestMethodNotSupportedException ) ex , headers , status , request );
@@ -181,38 +182,17 @@ else if (ex instanceof NoHandlerFoundException) {
181
182
}
182
183
else if (ex instanceof AsyncRequestTimeoutException ) {
183
184
HttpStatus status = HttpStatus .SERVICE_UNAVAILABLE ;
184
- return handleAsyncRequestTimeoutException (
185
- (AsyncRequestTimeoutException ) ex , headers , status , request );
185
+ return handleAsyncRequestTimeoutException ((AsyncRequestTimeoutException ) ex , headers , status , request );
186
186
}
187
187
else {
188
- if ( logger . isWarnEnabled ()) {
189
- logger . warn ( "Unknown exception type: " + ex . getClass (). getName ());
190
- }
191
- HttpStatus status = HttpStatus . INTERNAL_SERVER_ERROR ;
192
- return handleExceptionInternal ( ex , null , headers , status , request ) ;
188
+ // Unknown exception, typically a wrapper with a common MVC exception as cause
189
+ // (since @ExceptionHandler type declarations also match first-level causes):
190
+ // We only deal with top-level MVC exceptions here, so let's rethrow the given
191
+ // exception for further processing through the HandlerExceptionResolver chain.
192
+ throw ex ;
193
193
}
194
194
}
195
195
196
- /**
197
- * A single place to customize the response body of all Exception types.
198
- * <p>The default implementation sets the {@link WebUtils#ERROR_EXCEPTION_ATTRIBUTE}
199
- * request attribute and creates a {@link ResponseEntity} from the given
200
- * body, headers, and status.
201
- * @param ex the exception
202
- * @param body the body for the response
203
- * @param headers the headers for the response
204
- * @param status the response status
205
- * @param request the current request
206
- */
207
- protected ResponseEntity <Object > handleExceptionInternal (Exception ex , @ Nullable Object body ,
208
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
209
-
210
- if (HttpStatus .INTERNAL_SERVER_ERROR .equals (status )) {
211
- request .setAttribute (WebUtils .ERROR_EXCEPTION_ATTRIBUTE , ex , WebRequest .SCOPE_REQUEST );
212
- }
213
- return new ResponseEntity <>(body , headers , status );
214
- }
215
-
216
196
/**
217
197
* Customize the response for HttpRequestMethodNotSupportedException.
218
198
* <p>This method logs a warning, sets the "Allow" header, and delegates to
@@ -223,8 +203,8 @@ protected ResponseEntity<Object> handleExceptionInternal(Exception ex, @Nullable
223
203
* @param request the current request
224
204
* @return a {@code ResponseEntity} instance
225
205
*/
226
- protected ResponseEntity <Object > handleHttpRequestMethodNotSupported (HttpRequestMethodNotSupportedException ex ,
227
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
206
+ protected ResponseEntity <Object > handleHttpRequestMethodNotSupported (
207
+ HttpRequestMethodNotSupportedException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
228
208
229
209
pageNotFoundLogger .warn (ex .getMessage ());
230
210
@@ -245,8 +225,8 @@ protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequest
245
225
* @param request the current request
246
226
* @return a {@code ResponseEntity} instance
247
227
*/
248
- protected ResponseEntity <Object > handleHttpMediaTypeNotSupported (HttpMediaTypeNotSupportedException ex ,
249
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
228
+ protected ResponseEntity <Object > handleHttpMediaTypeNotSupported (
229
+ HttpMediaTypeNotSupportedException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
250
230
251
231
List <MediaType > mediaTypes = ex .getSupportedMediaTypes ();
252
232
if (!CollectionUtils .isEmpty (mediaTypes )) {
@@ -265,8 +245,8 @@ protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNo
265
245
* @param request the current request
266
246
* @return a {@code ResponseEntity} instance
267
247
*/
268
- protected ResponseEntity <Object > handleHttpMediaTypeNotAcceptable (HttpMediaTypeNotAcceptableException ex ,
269
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
248
+ protected ResponseEntity <Object > handleHttpMediaTypeNotAcceptable (
249
+ HttpMediaTypeNotAcceptableException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
270
250
271
251
return handleExceptionInternal (ex , null , headers , status , request );
272
252
}
@@ -281,8 +261,8 @@ protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(HttpMediaTypeN
281
261
* @return a {@code ResponseEntity} instance
282
262
* @since 4.2
283
263
*/
284
- protected ResponseEntity <Object > handleMissingPathVariable (MissingPathVariableException ex ,
285
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
264
+ protected ResponseEntity <Object > handleMissingPathVariable (
265
+ MissingPathVariableException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
286
266
287
267
return handleExceptionInternal (ex , null , headers , status , request );
288
268
}
@@ -296,8 +276,8 @@ protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableEx
296
276
* @param request the current request
297
277
* @return a {@code ResponseEntity} instance
298
278
*/
299
- protected ResponseEntity <Object > handleMissingServletRequestParameter (MissingServletRequestParameterException ex ,
300
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
279
+ protected ResponseEntity <Object > handleMissingServletRequestParameter (
280
+ MissingServletRequestParameterException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
301
281
302
282
return handleExceptionInternal (ex , null , headers , status , request );
303
283
}
@@ -311,8 +291,8 @@ protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingSer
311
291
* @param request the current request
312
292
* @return a {@code ResponseEntity} instance
313
293
*/
314
- protected ResponseEntity <Object > handleServletRequestBindingException (ServletRequestBindingException ex ,
315
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
294
+ protected ResponseEntity <Object > handleServletRequestBindingException (
295
+ ServletRequestBindingException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
316
296
317
297
return handleExceptionInternal (ex , null , headers , status , request );
318
298
}
@@ -326,8 +306,8 @@ protected ResponseEntity<Object> handleServletRequestBindingException(ServletReq
326
306
* @param request the current request
327
307
* @return a {@code ResponseEntity} instance
328
308
*/
329
- protected ResponseEntity <Object > handleConversionNotSupported (ConversionNotSupportedException ex ,
330
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
309
+ protected ResponseEntity <Object > handleConversionNotSupported (
310
+ ConversionNotSupportedException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
331
311
332
312
return handleExceptionInternal (ex , null , headers , status , request );
333
313
}
@@ -341,8 +321,8 @@ protected ResponseEntity<Object> handleConversionNotSupported(ConversionNotSuppo
341
321
* @param request the current request
342
322
* @return a {@code ResponseEntity} instance
343
323
*/
344
- protected ResponseEntity <Object > handleTypeMismatch (TypeMismatchException ex , HttpHeaders headers ,
345
- HttpStatus status , WebRequest request ) {
324
+ protected ResponseEntity <Object > handleTypeMismatch (
325
+ TypeMismatchException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
346
326
347
327
return handleExceptionInternal (ex , null , headers , status , request );
348
328
}
@@ -356,8 +336,8 @@ protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, Ht
356
336
* @param request the current request
357
337
* @return a {@code ResponseEntity} instance
358
338
*/
359
- protected ResponseEntity <Object > handleHttpMessageNotReadable (HttpMessageNotReadableException ex ,
360
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
339
+ protected ResponseEntity <Object > handleHttpMessageNotReadable (
340
+ HttpMessageNotReadableException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
361
341
362
342
return handleExceptionInternal (ex , null , headers , status , request );
363
343
}
@@ -371,8 +351,8 @@ protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotRead
371
351
* @param request the current request
372
352
* @return a {@code ResponseEntity} instance
373
353
*/
374
- protected ResponseEntity <Object > handleHttpMessageNotWritable (HttpMessageNotWritableException ex ,
375
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
354
+ protected ResponseEntity <Object > handleHttpMessageNotWritable (
355
+ HttpMessageNotWritableException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
376
356
377
357
return handleExceptionInternal (ex , null , headers , status , request );
378
358
}
@@ -386,8 +366,8 @@ protected ResponseEntity<Object> handleHttpMessageNotWritable(HttpMessageNotWrit
386
366
* @param request the current request
387
367
* @return a {@code ResponseEntity} instance
388
368
*/
389
- protected ResponseEntity <Object > handleMethodArgumentNotValid (MethodArgumentNotValidException ex ,
390
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
369
+ protected ResponseEntity <Object > handleMethodArgumentNotValid (
370
+ MethodArgumentNotValidException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
391
371
392
372
return handleExceptionInternal (ex , null , headers , status , request );
393
373
}
@@ -401,8 +381,8 @@ protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotV
401
381
* @param request the current request
402
382
* @return a {@code ResponseEntity} instance
403
383
*/
404
- protected ResponseEntity <Object > handleMissingServletRequestPart (MissingServletRequestPartException ex ,
405
- HttpHeaders headers , HttpStatus status , WebRequest request ) {
384
+ protected ResponseEntity <Object > handleMissingServletRequestPart (
385
+ MissingServletRequestPartException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
406
386
407
387
return handleExceptionInternal (ex , null , headers , status , request );
408
388
}
@@ -416,8 +396,8 @@ protected ResponseEntity<Object> handleMissingServletRequestPart(MissingServletR
416
396
* @param request the current request
417
397
* @return a {@code ResponseEntity} instance
418
398
*/
419
- protected ResponseEntity <Object > handleBindException (BindException ex , HttpHeaders headers ,
420
- HttpStatus status , WebRequest request ) {
399
+ protected ResponseEntity <Object > handleBindException (
400
+ BindException ex , HttpHeaders headers , HttpStatus status , WebRequest request ) {
421
401
422
402
return handleExceptionInternal (ex , null , headers , status , request );
423
403
}
@@ -467,4 +447,24 @@ protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
467
447
return handleExceptionInternal (ex , null , headers , status , webRequest );
468
448
}
469
449
450
+ /**
451
+ * A single place to customize the response body of all Exception types.
452
+ * <p>The default implementation sets the {@link WebUtils#ERROR_EXCEPTION_ATTRIBUTE}
453
+ * request attribute and creates a {@link ResponseEntity} from the given
454
+ * body, headers, and status.
455
+ * @param ex the exception
456
+ * @param body the body for the response
457
+ * @param headers the headers for the response
458
+ * @param status the response status
459
+ * @param request the current request
460
+ */
461
+ protected ResponseEntity <Object > handleExceptionInternal (
462
+ Exception ex , @ Nullable Object body , HttpHeaders headers , HttpStatus status , WebRequest request ) {
463
+
464
+ if (HttpStatus .INTERNAL_SERVER_ERROR .equals (status )) {
465
+ request .setAttribute (WebUtils .ERROR_EXCEPTION_ATTRIBUTE , ex , WebRequest .SCOPE_REQUEST );
466
+ }
467
+ return new ResponseEntity <>(body , headers , status );
468
+ }
469
+
470
470
}
0 commit comments