Skip to content

Commit 444573d

Browse files
committed
Display original request URI in NoResourceFoundException message
This commit ensures that the original request URI is displayed in `NoResourceFoundException` error messages when logged. Without this change, it can be confusing to see only the attempted resource path. There are cases where the original request was not meant for resource handling and we want to understand why this wasn't processed by another handler. The Problem Detail attribute has not been changed as the "instance" attribute already displays the request path. Closes gh-34553
1 parent d062552 commit 444573d

File tree

8 files changed

+98
-10
lines changed

8 files changed

+98
-10
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/resource/NoResourceFoundException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.web.reactive.resource;
1818

19+
import java.net.URI;
20+
1921
import org.springframework.http.HttpStatus;
2022
import org.springframework.web.server.ResponseStatusException;
2123

@@ -30,9 +32,9 @@
3032
public class NoResourceFoundException extends ResponseStatusException {
3133

3234

33-
public NoResourceFoundException(String resourcePath) {
34-
super(HttpStatus.NOT_FOUND, "No static resource " + resourcePath + ".");
35-
setDetail(getReason());
35+
public NoResourceFoundException(URI uri, String resourcePath) {
36+
super(HttpStatus.NOT_FOUND, "No static resource " + resourcePath + " for request '" + uri + "'.");
37+
setDetail("No static resource " + resourcePath + ".");
3638
}
3739

3840
}

spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ public Mono<Void> handle(ServerWebExchange exchange) {
420420
if (logger.isDebugEnabled()) {
421421
logger.debug(exchange.getLogPrefix() + "Resource not found");
422422
}
423-
return Mono.error(new NoResourceFoundException(getResourcePath(exchange)));
423+
return Mono.error(new NoResourceFoundException(exchange.getRequest().getURI(), getResourcePath(exchange)));
424424
}))
425425
.flatMap(resource -> {
426426
try {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.reactive.resource;
18+
19+
import java.net.URI;
20+
21+
import org.junit.jupiter.api.Test;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
/**
26+
* Tests for {@link NoResourceFoundException}.
27+
* @author Brian Clozel
28+
*/
29+
class NoResourceFoundExceptionTests {
30+
31+
@Test
32+
void messageShouldContainRequestUriAndResourcePath() {
33+
var noResourceFoundException = new NoResourceFoundException(URI.create("/context/resource"), "/resource");
34+
assertThat(noResourceFoundException.getMessage()).isEqualTo("404 NOT_FOUND \"No static resource /resource for request '/context/resource'.\"");
35+
}
36+
37+
@Test
38+
void detailShouldContainResourcePath() {
39+
var noResourceFoundException = new NoResourceFoundException(URI.create("/context/resource"), "/resource");
40+
assertThat(noResourceFoundException.getBody().getDetail()).isEqualTo("No static resource /resource.");
41+
}
42+
43+
}

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/NoResourceFoundException.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ public class NoResourceFoundException extends ServletException implements ErrorR
4545
/**
4646
* Create an instance.
4747
*/
48-
public NoResourceFoundException(HttpMethod httpMethod, String resourcePath) {
49-
super("No static resource " + resourcePath + ".");
48+
public NoResourceFoundException(HttpMethod httpMethod, String requestUri, String resourcePath) {
49+
super("No static resource " + resourcePath + " for request '" + requestUri + "'.");
5050
this.httpMethod = httpMethod;
5151
this.resourcePath = resourcePath;
52-
this.body = ProblemDetail.forStatusAndDetail(getStatusCode(), getMessage());
52+
this.body = ProblemDetail.forStatusAndDetail(getStatusCode(), "No static resource " + resourcePath + ".");
5353
}
5454

5555

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ public void handleRequest(HttpServletRequest request, HttpServletResponse respon
524524
Resource resource = getResource(request);
525525
if (resource == null) {
526526
logger.debug("Resource not found");
527-
throw new NoResourceFoundException(HttpMethod.valueOf(request.getMethod()), getPath(request));
527+
throw new NoResourceFoundException(HttpMethod.valueOf(request.getMethod()), request.getRequestURI(), getPath(request));
528528
}
529529

530530
if (HttpMethod.OPTIONS.matches(request.getMethod())) {

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ void noHandlerFoundException() {
306306

307307
@Test
308308
void noResourceFoundException() {
309-
testException(new NoResourceFoundException(HttpMethod.GET, "/resource"));
309+
testException(new NoResourceFoundException(HttpMethod.GET, "/context/resource", "/resource"));
310310
}
311311

312312
@Test

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolverTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void handleNoHandlerFoundException() {
209209

210210
@Test
211211
void handleNoResourceFoundException() {
212-
NoResourceFoundException ex = new NoResourceFoundException(HttpMethod.GET, "/resource");
212+
NoResourceFoundException ex = new NoResourceFoundException(HttpMethod.GET, "/context/resource", "/resource");
213213
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
214214
assertThat(mav).as("No ModelAndView returned").isNotNull();
215215
assertThat(mav.isEmpty()).as("No Empty ModelAndView returned").isTrue();
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.servlet.resource;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.http.HttpMethod;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
/**
26+
* Tests for {@link NoResourceFoundException}.
27+
* @author Brian Clozel
28+
*/
29+
class NoResourceFoundExceptionTests {
30+
31+
@Test
32+
void messageShouldContainRequestUriAndResourcePath() {
33+
var noResourceFoundException = new NoResourceFoundException(HttpMethod.GET, "/context/resource", "/resource");
34+
assertThat(noResourceFoundException.getMessage()).isEqualTo("No static resource /resource for request '/context/resource'.");
35+
}
36+
37+
@Test
38+
void detailShouldContainResourcePath() {
39+
var noResourceFoundException = new NoResourceFoundException(HttpMethod.GET, "/context/resource", "/resource");
40+
assertThat(noResourceFoundException.getBody().getDetail()).isEqualTo("No static resource /resource.");
41+
}
42+
43+
}

0 commit comments

Comments
 (0)