This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-21
Channels
- # announcements (7)
- # babashka (16)
- # beginners (174)
- # biff (7)
- # calva (20)
- # cider (3)
- # clerk (6)
- # cljsrn (4)
- # clojure (98)
- # clojure-europe (57)
- # clojure-italy (3)
- # clojure-nl (1)
- # clojure-portugal (1)
- # clojure-spec (15)
- # clojure-uk (7)
- # code-reviews (3)
- # cursive (23)
- # data-science (1)
- # datomic (26)
- # dev-tooling (2)
- # emacs (5)
- # figwheel-main (4)
- # fulcro (3)
- # honeysql (20)
- # hyperfiddle (20)
- # malli (8)
- # membrane (31)
- # nextjournal (5)
- # pathom (1)
- # polylith (20)
- # re-frame (14)
- # reitit (8)
- # releases (2)
- # shadow-cljs (50)
- # specter (2)
- # sql (22)
- # xtdb (5)
I'm having some trouble updating to the new authentication. I'm trying to sign in as a user that should already be in the database, but when I click the sign-in button, I get a java.lang.NullPointerException
. I was kind of knee-deep in the old authentication system (built some middleware to redirect folks to the page they wanted when they were prompted with a sign-in and added some default data to each user document when they first signed up), but I believe I've stripped all that out to make room for the new out and replaced it with the new stuff.
Here's the whole error:
[qtp1816737170-28] ERROR com.biffweb.impl.middleware - Exception while handling request
java.lang.NullPointerException
at com.biffweb.impl.auth$send_code_BANG_.invokeStatic(auth.clj:107)
at com.biffweb.impl.auth$send_code_BANG_.invoke(auth.clj:92)
at com.biffweb.impl.auth$send_code_handler.invokeStatic(auth.clj:167)
at com.biffweb.impl.auth$send_code_handler.invoke(auth.clj:162)
at com.biffweb.impl.auth$wrap_options$fn__23761.invoke(auth.clj:241)
at com.d1kh.middleware$wrap_hx_vals_convert$fn__44362.invoke(middleware.clj:69)
at com.biffweb.impl.middleware$wrap_render_rum$fn__25751.invoke(middleware.clj:36)
at com.biffweb.impl.middleware$wrap_anti_forgery_websockets$fn__25744.invoke(middleware.clj:32)
at ring.middleware.anti_forgery$wrap_anti_forgery$fn__22609.invoke(anti_forgery.clj:94)
at ring.middleware.session$wrap_session$fn__25209.invoke(session.clj:108)
at com.biffweb.impl.middleware$wrap_session$fn__25807.invoke(middleware.clj:141)
at muuntaja.middleware$wrap_params$fn__24783.invoke(middleware.clj:52)
at muuntaja.middleware$wrap_format$fn__24787.invoke(middleware.clj:73)
at ring.middleware.keyword_params$wrap_keyword_params$fn__25255.invoke(keyword_params.clj:53)
at ring.middleware.nested_params$wrap_nested_params$fn__25313.invoke(nested_params.clj:89)
at ring.middleware.multipart_params$wrap_multipart_params$fn__25445.invoke(multipart_params.clj:171)
at ring.middleware.params$wrap_params$fn__25472.invoke(params.clj:75)
at ring.middleware.cookies$wrap_cookies$fn__25088.invoke(cookies.clj:214)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__25626.invoke(absolute_redirects.clj:47)
at ring.middleware.content_type$wrap_content_type$fn__24820.invoke(content_type.clj:34)
at ring.middleware.default_charset$wrap_default_charset$fn__25598.invoke(default_charset.clj:31)
at ring.middleware.not_modified$wrap_not_modified$fn__25574.invoke(not_modified.clj:61)
at ring.middleware.x_headers$wrap_x_header$fn__24851.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__24851.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__24851.invoke(x_headers.clj:22)
at reitit.ring$ring_handler$fn__21688.invoke(ring.cljc:329)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.AFunction$1.doInvoke(AFunction.java:31)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at com.biffweb.impl.middleware$wrap_https_scheme$fn__25801.invoke(middleware.clj:111)
at com.biffweb.impl.middleware$wrap_resource$fn__25767.invoke(middleware.clj:62)
at com.biffweb.impl.middleware$wrap_internal_error$fn__25784.invoke(middleware.clj:80)
at com.biffweb.impl.middleware$wrap_ssl$fn__25812.invoke(middleware.clj:156)
at com.biffweb.impl.middleware$wrap_log_requests$fn__25795.invoke(middleware.clj:97)
at clojure.lang.Var.invoke(Var.java:384)
at com.biffweb.impl.middleware$use_wrap_ctx$fn__25822.invoke(middleware.clj:188)
at ring.adapter.jetty9$proxy_handler$fn__22256.invoke(jetty9.clj:75)
at ring.adapter.jetty9.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:1378)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463)
at ring.adapter.jetty9.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:1300)
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:562)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:418)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:675)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:410)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:101)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:412)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:381)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:268)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:138)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:407)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038)
at java.base/java.lang.Thread.run(Thread.java:829)
[qtp1816737170-28] INFO com.biffweb.impl.middleware - 51ms 500 post /auth/send-code
For what it's worth, starting a whole new project works fine. So I figure it's got to be something I'm missing.
This is the line referenced at the top of the stack trace: https://github.com/jacobobryant/biff/blob/6a5ba0a7a0a052d3ee88adaad645dcddf8bc3876/src/com/biffweb/impl/auth.clj#L107
Looks like send-email
is nil. You probably missed this bit: https://github.com/jacobobryant/biff/commit/6a5ba0a7a0a052d3ee88adaad645dcddf8bc3876#diff-dc8d794a683c27486f2b534a9fd84dab78e04d2c68963cd22dc776598320aa82R64
At some point I probably should start doing some argument validation so you get more helpful error messages than NullPointerException
🙂
> built some middleware to redirect folks to the page they wanted when they were prompted with a sign-in
I'd be down to add support for this to the auth plugin; probably by sticking a redirect
parameter inside the JWT. (Also feel free to stick with your own auth in the mean time if you prefer! As with all parts of Biff, it's idiomatic/recommended to roll your own whenever something that Biff provides doesn't quite do what you want.)
> and added some default data to each user document when they first signed up
You can do this if you pass in the :biff.auth/new-user-tx
option to biff/authentication-plugin
. There's a section about that in the https://biffweb.com/docs/api/authentication/--you can copy and paste the default new-user-tx
fn and modify as needed. Note that the first param (`ctx`) includes the ring request for the signup form, so you have access to any form parameters if needed.

> Looks like send-email
is nil. You probably missed this bit:
That was it!
I'm really excited about the new auth stuff. Aside from figuring out how to handle redirecting, it's pretty much doing what I want and I suspect it'll pass my "Will my parents be able to access my website without asking me for customer support every time?" test. And that's golden.
glad to hear it!