Skip to content

Commit ad45a94

Browse files
authored
Merge pull request springdoc#1320 from bespaltovyj/bugfix/fix-exception-handler-order
Fixed exception handler order
2 parents 7c96034 + d909674 commit ad45a94

File tree

7 files changed

+171
-1
lines changed

7 files changed

+171
-1
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ public Map<String, Object> getControllerAdviceMap() {
705705
Map<String, Object> controllerAdviceMap = context.getBeansWithAnnotation(ControllerAdvice.class);
706706
return Stream.of(controllerAdviceMap).flatMap(mapEl -> mapEl.entrySet().stream()).filter(
707707
controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(), Hidden.class) == null))
708-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
708+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1, LinkedHashMap::new));
709709
}
710710

711711
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.app166;
2+
3+
public class GlobalErrorResponseDto {
4+
5+
private String globalMessage;
6+
7+
public GlobalErrorResponseDto(String globalMessage) {
8+
this.globalMessage = globalMessage;
9+
}
10+
11+
public String getGlobalMessage() {
12+
return globalMessage;
13+
}
14+
15+
public void setGlobalMessage(String globalMessage) {
16+
this.globalMessage = globalMessage;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package test.org.springdoc.api.app166;
2+
3+
import org.springframework.stereotype.Component;
4+
import org.springframework.web.bind.annotation.ExceptionHandler;
5+
import org.springframework.web.bind.annotation.ResponseStatus;
6+
import org.springframework.web.bind.annotation.RestControllerAdvice;
7+
8+
@RestControllerAdvice
9+
@Component("1") // bean name override to simulate order in HashMap
10+
public class GlobalExceptionHandler {
11+
12+
@ExceptionHandler(RuntimeException.class)
13+
@ResponseStatus
14+
public GlobalErrorResponseDto processException() {
15+
return new GlobalErrorResponseDto("global");
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.app166;
2+
3+
public class LocalErrorResponseDto {
4+
5+
private String localMessage;
6+
7+
public LocalErrorResponseDto(String localMessage) {
8+
this.localMessage = localMessage;
9+
}
10+
11+
public String getLocalMessage() {
12+
return localMessage;
13+
}
14+
15+
public void setLocalMessage(String localMessage) {
16+
this.localMessage = localMessage;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
*
3+
* * Copyright 2019-2021 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app166;
20+
21+
import test.org.springdoc.api.AbstractSpringDocTest;
22+
23+
import org.springframework.boot.autoconfigure.SpringBootApplication;
24+
import org.springframework.test.context.TestPropertySource;
25+
26+
/**
27+
* In this test, it is checked that the error handler is displayed correctly in the documentation.
28+
* Exactly, that the local handler takes precedence over the global one
29+
* */
30+
@TestPropertySource(properties = "springdoc.api-docs.resolve-schema-properties=true")
31+
public class SpringDocApp166Test extends AbstractSpringDocTest {
32+
33+
@SpringBootApplication
34+
static class SpringDocTestApp {
35+
}
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.org.springdoc.api.app166;
2+
3+
import org.springframework.stereotype.Component;
4+
import org.springframework.web.bind.annotation.ExceptionHandler;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.ResponseStatus;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
@RestController
10+
@Component("0") // bean name override to simulate order in HashMap
11+
public class TestApiController {
12+
13+
@GetMapping(value = "/test")
14+
public String throwError() {
15+
throw new IllegalArgumentException();
16+
}
17+
18+
@ExceptionHandler(RuntimeException.class)
19+
@ResponseStatus
20+
public LocalErrorResponseDto processException() {
21+
return new LocalErrorResponseDto("local");
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/test": {
15+
"get": {
16+
"tags": [
17+
"test-api-controller"
18+
],
19+
"operationId": "throwError",
20+
"responses": {
21+
"500": {
22+
"description": "Internal Server Error",
23+
"content": {
24+
"*/*": {
25+
"schema": {
26+
"$ref": "#/components/schemas/LocalErrorResponseDto"
27+
}
28+
}
29+
}
30+
},
31+
"200": {
32+
"description": "OK",
33+
"content": {
34+
"*/*": {
35+
"schema": {
36+
"type": "string"
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
}
44+
},
45+
"components": {
46+
"schemas": {
47+
"LocalErrorResponseDto": {
48+
"type": "object",
49+
"properties": {
50+
"localMessage": {
51+
"type": "string"
52+
}
53+
}
54+
}
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)