Hi, where should I post an issue with pedestal? With the sawtooth router
If I run this
(require '[io.pedestal.http :as http])
(defonce server (atom nil))
(defn stop-server []
(when @server
(http/stop @server)
(reset! server nil)
(println "Server stopped")))
(do (defn start-server []
(let [service (-> {::http/routes
#{["/contacts/:id" :get (constantly {:status 200}) :route-name :get-contact]}
::http/type :jetty
::http/port 8080
::http/join? false}
http/create-server)]
(reset! server (http/start service))
(println "Pedestal server running at ")))
(do (stop-server) (start-server)))
; This will return 500. You can try it in the browser.
(slurp "")
The router will return 500, not 404 when accessing the /contacts routeDeps.edn
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}
io.pedestal/pedestal.jetty {:mvn/version "0.8.0-alpha-6"}}}This has not been my experience. Are you seeing a logged exception?
Your constantly should be treated as a handler function, so returning a response map should work.
The /contacts URL should not match your route, and one of the default interceptors, not-found, should convert that to a 404 (because no route matched, so no :response was every attached).
Full error:
Error processing request!
Exception:
java.lang.Thread.run Thread.java: 1575
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run QueuedThreadPool.java: 1166
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob QueuedThreadPool.java: 1211
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob QueuedThreadPool.java: 981
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce AdaptiveExecutionStrategy.java: 195
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce AdaptiveExecutionStrategy.java: 293
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask AdaptiveExecutionStrategy.java: 443
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask AdaptiveExecutionStrategy.java: 480
org.eclipse.jetty.io.SelectableChannelEndPoint$1.run SelectableChannelEndPoint.java: 53
org.eclipse.jetty.io.FillInterest.fillable FillInterest.java: 99
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded AbstractConnection.java: 322
org.eclipse.jetty.server.internal.HttpConnection.onFillable HttpConnection.java: 416
org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run HttpChannelState.java: 665
org.eclipse.jetty.server.Server.handle Server.java: 182
org.eclipse.jetty.server.handler.ContextHandler.handle ContextHandler.java: 1071
org.eclipse.jetty.ee10.servlet.SessionHandler.handle SessionHandler.java: 717
org.eclipse.jetty.ee10.servlet.ServletHandler.handle ServletHandler.java: 470
org.eclipse.jetty.ee10.servlet.ServletChannel.handle ServletChannel.java: 436
org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch ServletChannel.java: 819
org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle ServletHandler.java: 1555
org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter ServletHandler.java: 1594
org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter FilterHolder.java: 205
org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter WebSocketUpgradeFilter.java: 195
org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter ServletHandler.java: 1622
org.eclipse.jetty.ee10.servlet.ServletHolder.handle ServletHolder.java: 736
jakarta.servlet.http.HttpServlet.service HttpServlet.java: 614
io.pedestal.servlet.FnServlet.service FnServlet.java: 57
io.pedestal.http.impl.servlet-interceptor/interceptor-service-fn/fn servlet_interceptor.clj: 378
io.pedestal.interceptor.chain/execute chain.clj: 419
io.pedestal.interceptor.chain/execute chain.clj: 414
io.pedestal.interceptor.chain/execute-continue chain.clj: 352
io.pedestal.interceptor.chain/execute-enter chain.clj: 201
...
clojure.core/with-bindings* core.clj: 1990 (repeats 2 times)
...
io.pedestal.interceptor.chain/execute-enter/fn chain.clj: 221
io.pedestal.interceptor.chain/try-stage chain.clj: 109
io.pedestal.http.route/construct-router-interceptor-from-table/fn route.clj: 470
io.pedestal.http.route/route-context route.clj: 448
io.pedestal.http.route.sawtooth/router/fn sawtooth.clj: 34
io.pedestal.http.route.sawtooth/find-route sawtooth.clj: 20
io.pedestal.http.route.sawtooth.impl/subdivide-by-request-key/match-request-key-solo impl.clj: 379
io.pedestal.http.route.sawtooth.impl/match-by-path/match-on-path impl.clj: 331
io.pedestal.http.route.sawtooth.impl/matcher-by-first-token/fn impl.clj: 288
io.pedestal.http.route.sawtooth.impl/tail-param-matcher/match-tail-param impl.clj: 145
java.lang.NullPointerException: Cannot invoke "String.indexOf(String)" because "path__13240__auto__13282" is null
clojure.lang.ExceptionInfo: java.lang.NullPointerException in Interceptor :io.pedestal.http.route/router - Cannot invoke "String.indexOf(String)" because "path__13240__auto__13282" is null
exception-type: :java.lang.NullPointerException
execution-id: nil
interceptor: :io.pedestal.http.route/router
stage: :enter
Context:
{:io.pedestal.interceptor.chain/leave-queue
({:name :io.pedestal.http.cors/dev-allow-origin,
:enter
#object[io.pedestal.http.cors$fn__16353 0x3bf0dd96 "io.pedestal.http.cors$fn__16353@3bf0dd96"],
:leave nil,
:error nil}
{:name
:io.pedestal.http.impl.servlet-interceptor/apply-default-content-type,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$fn__17378 0x5b06d1ea "io.pedestal.http.impl.servlet_interceptor$fn__17378@5b06d1ea"],
:error nil}
{:name :io.pedestal.http.impl.servlet-interceptor/ring-response,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$leave_ring_response 0x42778d8b "io.pedestal.http.impl.servlet_interceptor$leave_ring_response@42778d8b"],
:error
#object[io.pedestal.http.impl.servlet_interceptor$error_ring_response 0x7c0fea6e "io.pedestal.http.impl.servlet_interceptor$error_ring_response@7c0fea6e"]}
{:name :io.pedestal.http.impl.servlet-interceptor/stylobate,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$leave_stylobate 0x3c6f9fe4 "io.pedestal.http.impl.servlet_interceptor$leave_stylobate@3c6f9fe4"],
:error
#object[io.pedestal.http.impl.servlet_interceptor$create_stylobate$fn__17374 0x4cb65e9a "io.pedestal.http.impl.servlet_interceptor$create_stylobate$fn__17374@4cb65e9a"]}),
:request
{:protocol "HTTP/1.1",
:async-supported? true,
:remote-addr "127.0.0.1",
:servlet-response
#object[org.eclipse.jetty.ee10.servlet.ServletApiResponse 0x1b4fdfa8 "ServletApiResponse@1b4fdfa8{org.eclipse.jetty.ee10.servlet.ServletContextResponse@4d144a55,org.eclipse.jetty.ee10.servlet.ServletContextResponse@4d144a55}"],
:servlet
#object[io.pedestal.servlet.FnServlet 0x7a56d128 "io.pedestal.servlet.FnServlet@7a56d128"],
:headers
{"origin" "",
"sec-fetch-site" "none",
"sec-ch-ua-mobile" "?0",
"host" "localhost:8080",
"user-agent"
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
"cookie" "ring-session=c2b581ca-e75a-419f-8463-4ebcfe104663",
"sec-fetch-user" "?1",
"sec-ch-ua"
"\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
"sec-ch-ua-platform" "\"macOS\"",
"connection" "keep-alive",
"upgrade-insecure-requests" "1",
"accept"
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language" "en-US,en;q=0.9,es-419;q=0.8,es;q=0.7",
"sec-fetch-dest" "document",
"accept-encoding" "gzip, deflate, br, zstd",
"sec-fetch-mode" "navigate",
"cache-control" "max-age=0"},
:server-port 8080,
:servlet-request
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0xeb8450c "ServletApiRequest@eb8450c{ServletContextRequest@614b380a{GET@12d4fc6f HTTP/1.1}}"],
:path-info "/contacts",
:uri "/contacts",
:server-name "localhost",
:query-string nil,
:body
#object[org.eclipse.jetty.ee10.servlet.HttpInput 0x36508602 "HttpInput@911246850 cs=ServletChannelState@4e2ccee0{s=HANDLING rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0} cp=org.eclipse.jetty.ee10.servlet.BlockingContentProducer@5111b4bb eof=false"],
:scheme :http,
:request-method :get,
:context-path ""},
:bindings {},
:io.pedestal.interceptor.chain/terminators
(#object[io.pedestal.http.response$terminate_when_response_STAR_ 0x64b90463 "io.pedestal.http.response$terminate_when_response_STAR_@64b90463"]),
:servlet-response
#object[org.eclipse.jetty.ee10.servlet.ServletApiResponse 0x1b4fdfa8 "ServletApiResponse@1b4fdfa8{org.eclipse.jetty.ee10.servlet.ServletContextResponse@4d144a55,org.eclipse.jetty.ee10.servlet.ServletContextResponse@4d144a55}"],
:servlet
#object[io.pedestal.servlet.FnServlet 0x7a56d128 "io.pedestal.servlet.FnServlet@7a56d128"],
:servlet-request
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0xeb8450c "ServletApiRequest@eb8450c{ServletContextRequest@614b380a{GET@12d4fc6f HTTP/1.1}}"],
:websocket-channel-source
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0xeb8450c "ServletApiRequest@eb8450c{ServletContextRequest@614b380a{GET@12d4fc6f HTTP/1.1}}"],
:io.pedestal.interceptor.chain/enter-async
[#object[io.pedestal.http.impl.servlet_interceptor$start_servlet_async 0xbaa6842 "io.pedestal.http.impl.servlet_interceptor$start_servlet_async@baa6842"]],
:io.pedestal.interceptor.chain/execution-id 2,
:servlet-config
#object[org.eclipse.jetty.ee10.servlet.ServletHolder$Config 0x621dd232 "org.eclipse.jetty.ee10.servlet.ServletHolder$Config@621dd232"]} Agree that it should return 404, but is returning 500. This is happening the the sawtooth router from the alpha
Ok, that's much more helpful.
And it could be a bug in sawtooth, that is where the exception occurs.
Could you try with alpha-7?
Same error.
Error processing request!
Exception:
java.lang.Thread.run Thread.java: 1575
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run QueuedThreadPool.java: 1166
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob QueuedThreadPool.java: 1211
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob QueuedThreadPool.java: 981
org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run ReservedThreadExecutor.java: 311
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run AdaptiveExecutionStrategy.java: 201
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce AdaptiveExecutionStrategy.java: 293
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask AdaptiveExecutionStrategy.java: 443
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask AdaptiveExecutionStrategy.java: 480
org.eclipse.jetty.io.SelectableChannelEndPoint$1.run SelectableChannelEndPoint.java: 53
org.eclipse.jetty.io.FillInterest.fillable FillInterest.java: 99
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded AbstractConnection.java: 322
org.eclipse.jetty.server.internal.HttpConnection.onFillable HttpConnection.java: 416
org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run HttpChannelState.java: 665
org.eclipse.jetty.server.Server.handle Server.java: 182
org.eclipse.jetty.server.handler.ContextHandler.handle ContextHandler.java: 1071
org.eclipse.jetty.ee10.servlet.SessionHandler.handle SessionHandler.java: 717
org.eclipse.jetty.ee10.servlet.ServletHandler.handle ServletHandler.java: 470
org.eclipse.jetty.ee10.servlet.ServletChannel.handle ServletChannel.java: 436
org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch ServletChannel.java: 819
org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle ServletHandler.java: 1555
org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter ServletHandler.java: 1594
org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter FilterHolder.java: 205
org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter WebSocketUpgradeFilter.java: 195
org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter ServletHandler.java: 1622
org.eclipse.jetty.ee10.servlet.ServletHolder.handle ServletHolder.java: 736
jakarta.servlet.http.HttpServlet.service HttpServlet.java: 614
io.pedestal.servlet.FnServlet.service FnServlet.java: 57
io.pedestal.http.impl.servlet-interceptor/interceptor-service-fn/fn servlet_interceptor.clj: 380
io.pedestal.interceptor.chain/execute chain.clj: 419
io.pedestal.interceptor.chain/execute chain.clj: 414
io.pedestal.interceptor.chain/execute-continue chain.clj: 352
io.pedestal.interceptor.chain/execute-enter chain.clj: 201
...
clojure.core/with-bindings* core.clj: 1990 (repeats 2 times)
...
io.pedestal.interceptor.chain/execute-enter/fn chain.clj: 221
io.pedestal.interceptor.chain/try-stage chain.clj: 109
io.pedestal.http.route/construct-router-interceptor-from-table/fn route.clj: 470
io.pedestal.http.route/route-context route.clj: 448
io.pedestal.http.route.sawtooth/router/fn sawtooth.clj: 34
io.pedestal.http.route.sawtooth/find-route sawtooth.clj: 20
io.pedestal.http.route.sawtooth.impl/subdivide-by-request-key/match-request-key-solo impl.clj: 379
io.pedestal.http.route.sawtooth.impl/match-by-path/match-on-path impl.clj: 331
io.pedestal.http.route.sawtooth.impl/matcher-by-first-token/fn impl.clj: 288
io.pedestal.http.route.sawtooth.impl/tail-param-matcher/match-tail-param impl.clj: 145
java.lang.NullPointerException: Cannot invoke "String.indexOf(String)" because "path__13237__auto__13279" is null
clojure.lang.ExceptionInfo: java.lang.NullPointerException in Interceptor :io.pedestal.http.route/router - Cannot invoke "String.indexOf(String)" because "path__13237__auto__13279" is null
exception-type: :java.lang.NullPointerException
execution-id: nil
interceptor: :io.pedestal.http.route/router
stage: :enter
Context:
{:io.pedestal.interceptor.chain/leave-queue
({:name :io.pedestal.http.cors/dev-allow-origin,
:enter
#object[io.pedestal.http.cors$fn__16350 0x23a1d973 "io.pedestal.http.cors$fn__16350@23a1d973"],
:leave nil,
:error nil}
{:name
:io.pedestal.http.impl.servlet-interceptor/apply-default-content-type,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$fn__17379 0x47ede2d2 "io.pedestal.http.impl.servlet_interceptor$fn__17379@47ede2d2"],
:error nil}
{:name :io.pedestal.http.impl.servlet-interceptor/ring-response,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$leave_ring_response 0xa365da2 "io.pedestal.http.impl.servlet_interceptor$leave_ring_response@a365da2"],
:error
#object[io.pedestal.http.impl.servlet_interceptor$error_ring_response 0x7f1933df "io.pedestal.http.impl.servlet_interceptor$error_ring_response@7f1933df"]}
{:name :io.pedestal.http.impl.servlet-interceptor/stylobate,
:enter nil,
:leave
#object[io.pedestal.http.impl.servlet_interceptor$leave_stylobate 0x604e2542 "io.pedestal.http.impl.servlet_interceptor$leave_stylobate@604e2542"],
:error
#object[io.pedestal.http.impl.servlet_interceptor$create_stylobate$fn__17375 0x66d25adf "io.pedestal.http.impl.servlet_interceptor$create_stylobate$fn__17375@66d25adf"]}),
:request
{:protocol "HTTP/1.1",
:async-supported? true,
:remote-addr "127.0.0.1",
:servlet-response
#object[org.eclipse.jetty.ee10.servlet.ServletApiResponse 0x5f520451 "ServletApiResponse@5f520451{org.eclipse.jetty.ee10.servlet.ServletContextResponse@33315c49,org.eclipse.jetty.ee10.servlet.ServletContextResponse@33315c49}"],
:servlet
#object[io.pedestal.servlet.FnServlet 0x5bf14588 "io.pedestal.servlet.FnServlet@5bf14588"],
:headers
{"origin" "",
"sec-fetch-site" "none",
"sec-ch-ua-mobile" "?0",
"host" "localhost:8080",
"user-agent"
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
"cookie" "ring-session=c2b581ca-e75a-419f-8463-4ebcfe104663",
"sec-fetch-user" "?1",
"sec-ch-ua"
"\"Google Chrome\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"",
"sec-ch-ua-platform" "\"macOS\"",
"connection" "keep-alive",
"upgrade-insecure-requests" "1",
"pragma" "no-cache",
"accept"
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language" "en-US,en;q=0.9,es-419;q=0.8,es;q=0.7",
"sec-fetch-dest" "document",
"accept-encoding" "gzip, deflate, br, zstd",
"sec-fetch-mode" "navigate",
"cache-control" "no-cache"},
:server-port 8080,
:servlet-request
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0x2c379000 "ServletApiRequest@2c379000{ServletContextRequest@1ef11fe7{GET@6d931857 HTTP/1.1}}"],
:path-info "/contacts",
:uri "/contacts",
:server-name "localhost",
:query-string nil,
:body
#object[org.eclipse.jetty.ee10.servlet.HttpInput 0x4ba66782 "HttpInput@1269196674 cs=ServletChannelState@6b613df6{s=HANDLING rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0} cp=org.eclipse.jetty.ee10.servlet.BlockingContentProducer@541cffd eof=false"],
:scheme :http,
:request-method :get,
:context-path ""},
:bindings {},
:io.pedestal.interceptor.chain/terminators
(#object[io.pedestal.http.response$terminate_when_response_STAR_ 0x5484f12c "io.pedestal.http.response$terminate_when_response_STAR_@5484f12c"]),
:servlet-response
#object[org.eclipse.jetty.ee10.servlet.ServletApiResponse 0x5f520451 "ServletApiResponse@5f520451{org.eclipse.jetty.ee10.servlet.ServletContextResponse@33315c49,org.eclipse.jetty.ee10.servlet.ServletContextResponse@33315c49}"],
:servlet
#object[io.pedestal.servlet.FnServlet 0x5bf14588 "io.pedestal.servlet.FnServlet@5bf14588"],
:servlet-request
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0x2c379000 "ServletApiRequest@2c379000{ServletContextRequest@1ef11fe7{GET@6d931857 HTTP/1.1}}"],
:websocket-channel-source
#object[org.eclipse.jetty.ee10.servlet.ServletApiRequest 0x2c379000 "ServletApiRequest@2c379000{ServletContextRequest@1ef11fe7{GET@6d931857 HTTP/1.1}}"],
:io.pedestal.interceptor.chain/enter-async
[#object[io.pedestal.http.impl.servlet_interceptor$start_servlet_async 0x336d20a8 "io.pedestal.http.impl.servlet_interceptor$start_servlet_async@336d20a8"]],
:io.pedestal.interceptor.chain/execution-id 10,
:servlet-config
#object[org.eclipse.jetty.ee10.servlet.ServletHolder$Config 0x2be15862 "org.eclipse.jetty.ee10.servlet.ServletHolder$Config@2be15862"]} Ok, I can look into this. Can you add an issue here: https://github.com/pedestal/pedestal/issues ?
Sure. Thanks for taking a look
Fix was easy, will be in the next release.
woohoo Nice, thanks!