Hi, has anyone managed to implement a custom error page when the user makes a request to a non-existing path?
I am not as familiar with reitit but that is the stacktrace you get if your ring handler returns nil instead of a resp map to the ring jetty adapter
So likely you need to add some kind of catch all route to reitit before turning it into a ring handler there is a #reitit specific channel as well
https://cljdoc.org/d/metosin/reitit/0.7.0/doc/ring/default-handler
Yes
Ring is a mapping of http requests to clojure functions and does not prescribe routing, there are many routing libraries that people use with ring, and the routing library you use will dictate how you do this.
Compojure is a common routing library and for compojure each route is tried in order, so just put a route at the end that returns a custom 404
Yes, we use reitit But in this case, if the user makes a request to non-existing url, it never reaches reitit. The exception comes from ring/jetty level.
Like this:
java.lang.NullPointerException: Response map is nil
at ring.util.jakarta.servlet$update_servlet_response.invokeStatic(servlet.clj:91)
at ring.util.jakarta.servlet$update_servlet_response.invoke(servlet.clj:82)
at ring.util.jakarta.servlet$update_servlet_response.invokeStatic(servlet.clj:86)
at ring.util.jakarta.servlet$update_servlet_response.invoke(servlet.clj:82)
at ring.adapter.jetty$proxy_handler$fn__3281.invoke(jetty.clj:111)
at ring.adapter.jetty.proxy$org.eclipse.jetty.servlet.ServletHandler$ff19274a.doHandle(Unknown Source)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
at ring.adapter.jetty.proxy$org.eclipse.jetty.servlet.ServletHandler$ff19274a.doScope(Unknown Source)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
at org.eclipse.jetty.server.Server.handle(Server.java:563)
at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
at java.base/java.lang.Thread.run(Thread.java:830)I actually added a Ring example recently that uses Reitit and the default handler: https://github.com/ring-clojure/ring-examples/blob/master/hello-world/src/ring/example/hello/server.clj