Skip to content

[BUG] PageNotFound exception results in HTTP 500 (should be 404) #81

@lestephane

Description

@lestephane

Describe the bug
Getting an HTTP 500 (internal server error) when issuing a request for a path + method combination that the server does not know about.

To Reproduce
Server configuration

public final class Server {
  public static void main(String[] args) {
    serverInstance(8080).run();
  }

  @NotNull
  private static QuantumMaid serverInstance(int port) {
    QuantumMaid quantumMaid = quantumMaid()
        .withHttpMaid(anHttpMaid()
            .get("/*", dumpRequest())
            //.options("/*", dumpRequest())
            //.patch("/*", dumpRequest())
            .post("/*", dumpRequest())
            .put("/*", dumpRequest())
            .delete("/*", dumpRequest()).build())
        .withLocalHostEndpointOnPort(port);
    return quantumMaid;
  }

  private static HttpHandler dumpRequest() {
    return (request, response) ->
      System.err.printf("%s %s %n", request.method(), request.path());
  }
}

client request

$ curl -v localhost:8080 -XOPTIONS
* Rebuilt URL to: localhost:8080/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> OPTIONS / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< Date: Sun, 31 May 2020 18:47:27 GMT
< Transfer-encoding: chunked
< 
* Connection #0 to host localhost left intact

Server STDERR output

21:47:27.449 [HTTP-Dispatcher] ERROR de.quantummaid.httpmaid.exceptions.DefaultExceptionMapper - Exception during request processing
PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 500
REQUEST_BODY_STRING = 
EXCEPTION = de.quantummaid.httpmaid.handler.PageNotFoundException: No handler found for path '/' and method 'OPTIONS'

PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 200
REQUEST_BODY_STRING = 
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@37224855
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@37224855
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
de.quantummaid.httpmaid.handler.PageNotFoundException: No handler found for path '/' and method 'OPTIONS'

PATH = Path(path=/)
QUERY_PARAMETERS = QueryParameters(queryParameters={})
RESPONSE_STATUS = 200
REQUEST_BODY_STRING = 
UNMARSHALLED_REQUEST_BODY = null
RAW_METHOD = OPTIONS
IS_HTTP_REQUEST = true
REQUEST_CONTENT_TYPE = ContentType(value=null)
RESPONSE_HEADERS = {}
REQUEST_BODY_STREAM = sun.net.httpserver.FixedLengthInputStream@37224855
RAW_PATH = /
RAW_REQUEST_QUERY_PARAMETERS = {}
METHOD = HttpRequestMethod(value=OPTIONS)
RAW_REQUEST_HEADERS = sun.net.httpserver.UnmodifiableHeaders@29740f87
REQUEST_HEADERS = Headers(headers={HeaderKey(value=user-agent)=HeaderValue(value=curl/7.47.0), HeaderKey(value=host)=HeaderValue(value=localhost:8080), HeaderKey(value=accept)=HeaderValue(value=*/*)})
	at de.quantummaid.httpmaid.handler.PageNotFoundException.pageNotFoundException(PageNotFoundException.java:41)
	at de.quantummaid.httpmaid.handler.InvokeHandlerProcessor.lambda$apply$0(InvokeHandlerProcessor.java:45)
	at java.base/java.util.Optional.orElseThrow(Optional.java:408)
	at de.quantummaid.httpmaid.handler.InvokeHandlerProcessor.apply(InvokeHandlerProcessor.java:45)
	at de.quantummaid.httpmaid.chains.Chain.lambda$accept$0(Chain.java:74)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1239)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
	at de.quantummaid.httpmaid.chains.Chain.accept(Chain.java:74)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:69)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.handleAction(ChainRegistry.java:78)
	at de.quantummaid.httpmaid.chains.ChainRegistry.accept(ChainRegistry.java:70)
	at de.quantummaid.httpmaid.chains.ChainRegistry.putIntoChain(ChainRegistry.java:63)
	at de.quantummaid.httpmaid.HttpMaid.handleRequest(HttpMaid.java:85)
	at de.quantummaid.httpmaid.endpoint.purejavaendpoint.PureJavaEndpointHandler.handle(PureJavaEndpointHandler.java:48)
	at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
	at jdk.httpserver/sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:82)
	at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
	at jdk.httpserver/sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:692)
	at jdk.httpserver/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
	at jdk.httpserver/sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:664)
	at jdk.httpserver/sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:159)
	at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:442)
	at jdk.httpserver/sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:408)
	at java.base/java.lang.Thread.run(Thread.java:834)

Expected behavior
When a request is not routable because no rules have been configured for the request path and method combination, the http status code should return 404 (NOT FOUND).

  • project version used: 0.9.64 (BOM 1.0.48)
  • Java version used: 11

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions