1
1
/*
2
- * Copyright 2002-2018 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
19
19
import org .junit .Test ;
20
20
21
+ import org .springframework .core .Ordered ;
22
+ import org .springframework .core .annotation .Order ;
23
+ import org .springframework .http .MediaType ;
21
24
import org .springframework .stereotype .Controller ;
22
25
import org .springframework .web .bind .annotation .ControllerAdvice ;
23
26
import org .springframework .web .bind .annotation .ExceptionHandler ;
24
27
import org .springframework .web .bind .annotation .GetMapping ;
25
28
import org .springframework .web .bind .annotation .PathVariable ;
29
+ import org .springframework .web .bind .annotation .RestController ;
30
+ import org .springframework .web .bind .annotation .RestControllerAdvice ;
26
31
27
32
import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .*;
28
33
import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .*;
32
37
* Exception handling via {@code @ExceptionHandler} method.
33
38
*
34
39
* @author Rossen Stoyanchev
40
+ * @author Sam Brannen
35
41
*/
36
42
public class ExceptionHandlerTests {
37
43
38
44
@ Test
39
- public void testExceptionHandlerMethod () throws Exception {
45
+ public void mvcLocalExceptionHandlerMethod () throws Exception {
40
46
standaloneSetup (new PersonController ()).build ()
41
- .perform (get ("/person/Clyde" ))
47
+ .perform (get ("/person/Clyde" ))
42
48
.andExpect (status ().isOk ())
43
49
.andExpect (forwardedUrl ("errorView" ));
44
50
}
45
51
46
52
@ Test
47
- public void testGlobalExceptionHandlerMethod () throws Exception {
53
+ public void mvcGlobalExceptionHandlerMethod () throws Exception {
48
54
standaloneSetup (new PersonController ()).setControllerAdvice (new GlobalExceptionHandler ()).build ()
49
55
.perform (get ("/person/Bonnie" ))
50
56
.andExpect (status ().isOk ())
51
57
.andExpect (forwardedUrl ("globalErrorView" ));
52
58
}
53
59
54
60
@ Test
55
- public void testGlobalExceptionHandlerMethodUsingClassArgument () throws Exception {
61
+ public void mvcGlobalExceptionHandlerMethodUsingClassArgument () throws Exception {
56
62
standaloneSetup (PersonController .class ).setControllerAdvice (GlobalExceptionHandler .class ).build ()
57
63
.perform (get ("/person/Bonnie" ))
58
64
.andExpect (status ().isOk ())
59
65
.andExpect (forwardedUrl ("globalErrorView" ));
60
66
}
61
67
68
+ @ Test
69
+ public void restNoException () throws Exception {
70
+ standaloneSetup (RestPersonController .class )
71
+ .setControllerAdvice (RestGlobalExceptionHandler .class , RestPersonControllerExceptionHandler .class ).build ()
72
+ .perform (get ("/person/Yoda" ).accept (MediaType .APPLICATION_JSON ))
73
+ .andExpect (status ().isOk ())
74
+ .andExpect (jsonPath ("$.name" ).value ("Yoda" ));
75
+ }
76
+
77
+ @ Test
78
+ public void restLocalExceptionHandlerMethod () throws Exception {
79
+ standaloneSetup (RestPersonController .class )
80
+ .setControllerAdvice (RestGlobalExceptionHandler .class , RestPersonControllerExceptionHandler .class ).build ()
81
+ .perform (get ("/person/Luke" ).accept (MediaType .APPLICATION_JSON ))
82
+ .andExpect (status ().isOk ())
83
+ .andExpect (jsonPath ("$.error" ).value ("local - IllegalArgumentException" ));
84
+ }
85
+
86
+ @ Test
87
+ public void restGlobalExceptionHandlerMethod () throws Exception {
88
+ standaloneSetup (RestPersonController .class )
89
+ .setControllerAdvice (RestGlobalExceptionHandler .class ).build ()
90
+ .perform (get ("/person/Leia" ).accept (MediaType .APPLICATION_JSON ))
91
+ .andExpect (status ().isOk ())
92
+ .andExpect (jsonPath ("$.error" ).value ("global - IllegalStateException" ));
93
+ }
94
+
95
+ @ Test
96
+ public void restGlobalRestPersonControllerExceptionHandlerTakesPrecedenceOverGlobalExceptionHandler () throws Exception {
97
+ standaloneSetup (RestPersonController .class )
98
+ .setControllerAdvice (RestGlobalExceptionHandler .class , RestPersonControllerExceptionHandler .class ).build ()
99
+ .perform (get ("/person/Leia" ).accept (MediaType .APPLICATION_JSON ))
100
+ .andExpect (status ().isOk ())
101
+ .andExpect (jsonPath ("$.error" ).value ("globalPersonController - IllegalStateException" ));
102
+ }
103
+
104
+ @ Test // gh-25520
105
+ public void restNoHandlerFound () throws Exception {
106
+ standaloneSetup (RestPersonController .class )
107
+ .setControllerAdvice (RestGlobalExceptionHandler .class , RestPersonControllerExceptionHandler .class )
108
+ .addDispatcherServletCustomizer (dispatcherServlet -> dispatcherServlet .setThrowExceptionIfNoHandlerFound (true ))
109
+ .build ()
110
+ .perform (get ("/bogus" ).accept (MediaType .APPLICATION_JSON ))
111
+ .andExpect (status ().isOk ())
112
+ .andExpect (jsonPath ("$.error" ).value ("global - NoHandlerFoundException" ));
113
+ }
114
+
62
115
63
116
@ Controller
64
117
private static class PersonController {
@@ -80,15 +133,80 @@ public String handleException(IllegalArgumentException exception) {
80
133
}
81
134
}
82
135
83
-
84
136
@ ControllerAdvice
85
137
private static class GlobalExceptionHandler {
86
138
87
139
@ ExceptionHandler
88
140
public String handleException (IllegalStateException exception ) {
89
141
return "globalErrorView" ;
90
142
}
143
+ }
144
+
145
+ @ RestController
146
+ private static class RestPersonController {
147
+
148
+ @ GetMapping ("/person/{name}" )
149
+ Person get (@ PathVariable String name ) {
150
+ switch (name ) {
151
+ case "Luke" :
152
+ throw new IllegalArgumentException ();
153
+ case "Leia" :
154
+ throw new IllegalStateException ();
155
+ default :
156
+ return new Person ("Yoda" );
157
+ }
158
+ }
91
159
160
+ @ ExceptionHandler
161
+ Error handleException (IllegalArgumentException exception ) {
162
+ return new Error ("local - " + exception .getClass ().getSimpleName ());
163
+ }
164
+ }
165
+
166
+ @ RestControllerAdvice (assignableTypes = RestPersonController .class )
167
+ @ Order (Ordered .HIGHEST_PRECEDENCE )
168
+ private static class RestPersonControllerExceptionHandler {
169
+
170
+ @ ExceptionHandler
171
+ Error handleException (Throwable exception ) {
172
+ return new Error ("globalPersonController - " + exception .getClass ().getSimpleName ());
173
+ }
174
+ }
175
+
176
+ @ RestControllerAdvice
177
+ @ Order (Ordered .LOWEST_PRECEDENCE )
178
+ private static class RestGlobalExceptionHandler {
179
+
180
+ @ ExceptionHandler
181
+ Error handleException (Throwable exception ) {
182
+ return new Error ( "global - " + exception .getClass ().getSimpleName ());
183
+ }
184
+ }
185
+
186
+ static class Person {
187
+
188
+ private final String name ;
189
+
190
+ Person (String name ) {
191
+ this .name = name ;
192
+ }
193
+
194
+ public String getName () {
195
+ return name ;
196
+ }
197
+ }
198
+
199
+ static class Error {
200
+
201
+ private final String error ;
202
+
203
+ Error (String error ) {
204
+ this .error = error ;
205
+ }
206
+
207
+ public String getError () {
208
+ return error ;
209
+ }
92
210
}
93
211
94
212
}
0 commit comments