为什么我在 Luminus (Clojure) 中看到参数不匹配错误?
Why am I seeing Parameter Mismatch error in Luminus (Clojure)?
编辑(固定)...
如果您遵循 Luminus guestbook tutorial 或修改其中的部分内容,您可能会遇到类似 Parameter Mismatch: :name parameter data not found.
的错误,并且无论您使用什么参数,它都不会消失。您可能会发现您正在尝试调用一个不存在的函数,并且 Conman/HugSQL 不知道如何处理它。
我的问题的答案在以下部分:
代码的相关部分在myapp.routes.home/create-user!
(defn create-user! [{:keys [params]}]
(if-let [errors (validate-user params)]
(-> (response/found "/users")
(assoc :flash (assoc params :errors errors)))
(do
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8)))
(response/found "/users"))))
下面的代码不正确:
:pass (generate-password 8)) ; <-- 2 parentheses at the end of line.
(response/found "/users"))))) ; <-- 5 parentheses at the end of line.
我通过如下所示更改它来修复它:
:pass (generate-password 8))) ; <-- 3 parentheses at the end of line.
(response/found "/users")))) ; <-- 4 parentheses at the end of line.
原来我向 db/create-user 传递了错误数量的参数!康曼似乎不知道如何调用查询。
此外,我草率地修复了迁移中的一些问题 - 通过编辑已发生的迁移。我注意到 Conman 似乎没有注意到您是否正在更改旧的迁移和 queries.sql 文件。如果你发现 queries.sql 没有反映你的数据库 api (所以当你将 id 字段设置为自动递增时你仍然收到关于 ID 参数的消息,那么你需要让 Conman 重新生成你的DB API.
这可以在 REPL 中完成,如下所示:
user> (ns myapp.db.core)
nil
myapp.db.core> (conman/bind-connection *db* "sql/queries.sql")
原post以下
我正在或多或少基于 the Luminus guestbook tutorial and I'm just trying to test the create-user!
form at http://localhost:3000/users 构建的非常简单的应用程序。每当我提交表单时,我都会得到 Parameter Mismatch: :username parameter data not found.
的一些变体,它并不特定于 :username
。无论我发送什么参数,我都会得到 :first_name parameter data not found.
或类似的东西。
这是扩展的参数部分:
我已经在 myapp.routes.home/create-user!
中完成了 println
并且我知道参数似乎在那之前都存在。我不确定如何进一步追踪它。我会很感激从这里调试的任何建议,而且如果有人看到我做错了什么,那将非常有帮助。
堆栈跟踪:
$ lein run
2020-03-22 16:34:47,244 [main] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
2020-03-22 16:34:47,897 [main] INFO myapp.env -
-=[myapp started successfully using the development profile]=-
2020-03-22 16:34:48,471 [main] INFO luminus.http-server - starting HTTP server on port 3000
2020-03-22 16:34:48,496 [main] DEBUG io.undertow - starting undertow server io.undertow.Undertow@591ea3da
2020-03-22 16:34:48,503 [main] INFO org.xnio - XNIO version 3.3.6.Final
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.xnio.nio.NioXnio (file:/Users/mattlally/.m2/repository/org/jboss/xnio/xnio-nio/3.3.6.Final/xnio-nio-3.3.6.Final.jar) to constructor sun.nio.ch.KQueueSelectorProvider()
WARNING: Please consider reporting this to the maintainers of org.xnio.nio.NioXnio
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2020-03-22 16:34:48,616 [main] DEBUG io.undertow - Configuring listener with protocol HTTP for interface 0.0.0.0 and port 3000
2020-03-22 16:34:48,659 [main] INFO org.projectodd.wunderboss.web.Web - Registered web context /
2020-03-22 16:34:48,659 [main] INFO myapp.nrepl - starting nREPL server on port 7000
2020-03-22 16:34:48,676 [main] INFO myapp.core - #'myapp.db.core/*db* started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.handler/init-app started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.handler/app-routes started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.core/http-server started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.core/repl-server started
java.lang.Exception: Exception in :create-user!
at conman.core$try_query$fn__33540$fn__33541.invoke(core.clj:32)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$apply.invoke(core.clj:660)
at myapp.db.core$eval35973$f__33568__auto____36000.doInvoke(core.clj:13)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at myapp.routes.home$create_user_BANG_.invokeStatic(home.clj:46)
at myapp.routes.home$create_user_BANG_.invoke(home.clj:41)
at muuntaja.middleware$wrap_params$fn__28296.invoke(middleware.clj:52)
at muuntaja.middleware$wrap_format$fn__28300.invoke(middleware.clj:73)
at myapp.middleware$wrap_formats$fn__31491.invoke(middleware.clj:42)
at ring.middleware.anti_forgery$wrap_anti_forgery$fn__27132.invoke(anti_forgery.clj:94)
at reitit.ring$ring_handler$fn__38011.invoke(ring.cljc:292)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.AFunction.doInvoke(AFunction.java:31)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:384)
at ring.middleware.reload$wrap_reload$fn__24791.invoke(reload.clj:39)
at selmer.middleware$wrap_error_page$fn__24806.invoke(middleware.clj:18)
at prone.middleware$wrap_exceptions$fn__25047.invoke(middleware.clj:159)
at ring.middleware.flash$wrap_flash$fn__28337.invoke(flash.clj:39)
at immutant.web.internal.undertow$wrap_undertow_session$fn__39192.invoke(undertow.clj:72)
at ring.middleware.keyword_params$wrap_keyword_params$fn__31059.invoke(keyword_params.clj:53)
at ring.middleware.nested_params$wrap_nested_params$fn__31117.invoke(nested_params.clj:89)
at ring.middleware.multipart_params$wrap_multipart_params$fn__31249.invoke(multipart_params.clj:173)
at ring.middleware.params$wrap_params$fn__31273.invoke(params.clj:67)
at ring.middleware.cookies$wrap_cookies$fn__30892.invoke(cookies.clj:214)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__31411.invoke(absolute_redirects.clj:47)
at ring.middleware.resource$wrap_resource_prefer_resources$fn__31309.invoke(resource.clj:25)
at ring.middleware.content_type$wrap_content_type$fn__31359.invoke(content_type.clj:34)
at ring.middleware.default_charset$wrap_default_charset$fn__31383.invoke(default_charset.clj:31)
at ring.middleware.not_modified$wrap_not_modified$fn__19539.invoke(not_modified.clj:61)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at myapp.middleware$wrap_internal_error$fn__31485.invoke(middleware.clj:21)
at immutant.web.internal.undertow$create_http_handler$reify__39303.handleRequest(undertow.clj:239)
at org.projectodd.wunderboss.web.undertow.async.websocket.UndertowWebsocket.handleRequest(UndertowWebsocket.java:109)
at io.undertow.server.session.SessionAttachmentHandler.handleRequest(SessionAttachmentHandler.java:68)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:211)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:809)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: clojure.lang.ExceptionInfo: Parameter Mismatch: :username parameter data not found. {}
at hugsql.core$validate_parameters_BANG_.invokeStatic(core.clj:83)
at hugsql.core$validate_parameters_BANG_.invoke(core.clj:69)
at hugsql.core$prepare_sql.invokeStatic(core.clj:185)
at hugsql.core$prepare_sql.invoke(core.clj:173)
at hugsql.core$db_fn_STAR_$y__33452.doInvoke(core.clj:457)
at clojure.lang.RestFn.invoke(RestFn.java:445)
at hugsql.core$db_fn_STAR_$y__33452.invoke(core.clj:448)
at conman.core$try_query$fn__33540$fn__33541.invoke(core.clj:30)
... 45 more
在 db/create-user! 的调用中,在 myapp.routes.home/create-user! 中,我无意中传递了一个额外的参数。当康曼试图用它做点什么时,它就炸开了锅。原文中的代码和解释post。
简短回答:我错误地计算了我的括号。 :/
我也 运行 解决了这个问题,您希望表达式的 return 值与代码块的内容不同。它会产生我所说的 "hanging expression" 问题,并且很容易放错或忽略最后一点代码,尤其是在大型 do
块(或类似 when
、when-not
,等等)。即使使用代码格式化程序(如 IntelliJ IDEA/Cursive),也不容易验证代码对齐和括号位置是否正确。
为了使这样的代码块更易于阅读,我创建了一个超级简单的宏 with-result
in the Tupelo library。实现差不多就是学习宏的"Hello World":
(defmacro with-result
"Evaluates `result` and returns it; also evaluates `forms` for their side-effects."
[result & forms]
`(let [result# ~result]
(do ~@forms)
result#))
使用 with-result
宏,您的代码将变为以下内容:
(ns tst.demo.core
(:require [tupelo.core :as t]))
(defn create-user! [{:keys [params]}]
(if-let [errors (validate-user params)]
; found existing user
(-> (response/found "/users")
(assoc :flash (assoc params :errors errors)))
; need to create new user
(t/with-result (response/found "/users")
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8))))))
你可以看到我添加了简单的评论来帮助衬托 if
的每个分支并总结它的作用。
您还可以选择通过在一个地方调用 (response/found ...)
来进一步简化:
(defn create-user! [{:keys [params]}]
(let [errors (validate-user params)
response (response/found "/users")]
(if errors
(assoc response :flash (assoc params :errors errors))
(t/with-result response
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8)))))))
with-result
对于在离开函数之前打印 return 值也非常方便,或者对于 core.async
代码,其中 core.async
通道必须是 returned在一个大代码块的末尾。
编辑(固定)...
如果您遵循 Luminus guestbook tutorial 或修改其中的部分内容,您可能会遇到类似 Parameter Mismatch: :name parameter data not found.
的错误,并且无论您使用什么参数,它都不会消失。您可能会发现您正在尝试调用一个不存在的函数,并且 Conman/HugSQL 不知道如何处理它。
我的问题的答案在以下部分:
代码的相关部分在myapp.routes.home/create-user!
(defn create-user! [{:keys [params]}]
(if-let [errors (validate-user params)]
(-> (response/found "/users")
(assoc :flash (assoc params :errors errors)))
(do
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8)))
(response/found "/users"))))
下面的代码不正确:
:pass (generate-password 8)) ; <-- 2 parentheses at the end of line.
(response/found "/users"))))) ; <-- 5 parentheses at the end of line.
我通过如下所示更改它来修复它:
:pass (generate-password 8))) ; <-- 3 parentheses at the end of line.
(response/found "/users")))) ; <-- 4 parentheses at the end of line.
原来我向 db/create-user 传递了错误数量的参数!康曼似乎不知道如何调用查询。
此外,我草率地修复了迁移中的一些问题 - 通过编辑已发生的迁移。我注意到 Conman 似乎没有注意到您是否正在更改旧的迁移和 queries.sql 文件。如果你发现 queries.sql 没有反映你的数据库 api (所以当你将 id 字段设置为自动递增时你仍然收到关于 ID 参数的消息,那么你需要让 Conman 重新生成你的DB API.
这可以在 REPL 中完成,如下所示:
user> (ns myapp.db.core)
nil
myapp.db.core> (conman/bind-connection *db* "sql/queries.sql")
原post以下
我正在或多或少基于 the Luminus guestbook tutorial and I'm just trying to test the create-user!
form at http://localhost:3000/users 构建的非常简单的应用程序。每当我提交表单时,我都会得到 Parameter Mismatch: :username parameter data not found.
的一些变体,它并不特定于 :username
。无论我发送什么参数,我都会得到 :first_name parameter data not found.
或类似的东西。
这是扩展的参数部分:
我已经在 myapp.routes.home/create-user!
中完成了 println
并且我知道参数似乎在那之前都存在。我不确定如何进一步追踪它。我会很感激从这里调试的任何建议,而且如果有人看到我做错了什么,那将非常有帮助。
堆栈跟踪:
$ lein run
2020-03-22 16:34:47,244 [main] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
2020-03-22 16:34:47,897 [main] INFO myapp.env -
-=[myapp started successfully using the development profile]=-
2020-03-22 16:34:48,471 [main] INFO luminus.http-server - starting HTTP server on port 3000
2020-03-22 16:34:48,496 [main] DEBUG io.undertow - starting undertow server io.undertow.Undertow@591ea3da
2020-03-22 16:34:48,503 [main] INFO org.xnio - XNIO version 3.3.6.Final
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.xnio.nio.NioXnio (file:/Users/mattlally/.m2/repository/org/jboss/xnio/xnio-nio/3.3.6.Final/xnio-nio-3.3.6.Final.jar) to constructor sun.nio.ch.KQueueSelectorProvider()
WARNING: Please consider reporting this to the maintainers of org.xnio.nio.NioXnio
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2020-03-22 16:34:48,616 [main] DEBUG io.undertow - Configuring listener with protocol HTTP for interface 0.0.0.0 and port 3000
2020-03-22 16:34:48,659 [main] INFO org.projectodd.wunderboss.web.Web - Registered web context /
2020-03-22 16:34:48,659 [main] INFO myapp.nrepl - starting nREPL server on port 7000
2020-03-22 16:34:48,676 [main] INFO myapp.core - #'myapp.db.core/*db* started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.handler/init-app started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.handler/app-routes started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.core/http-server started
2020-03-22 16:34:48,677 [main] INFO myapp.core - #'myapp.core/repl-server started
java.lang.Exception: Exception in :create-user!
at conman.core$try_query$fn__33540$fn__33541.invoke(core.clj:32)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$apply.invoke(core.clj:660)
at myapp.db.core$eval35973$f__33568__auto____36000.doInvoke(core.clj:13)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at myapp.routes.home$create_user_BANG_.invokeStatic(home.clj:46)
at myapp.routes.home$create_user_BANG_.invoke(home.clj:41)
at muuntaja.middleware$wrap_params$fn__28296.invoke(middleware.clj:52)
at muuntaja.middleware$wrap_format$fn__28300.invoke(middleware.clj:73)
at myapp.middleware$wrap_formats$fn__31491.invoke(middleware.clj:42)
at ring.middleware.anti_forgery$wrap_anti_forgery$fn__27132.invoke(anti_forgery.clj:94)
at reitit.ring$ring_handler$fn__38011.invoke(ring.cljc:292)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.AFunction.doInvoke(AFunction.java:31)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:384)
at ring.middleware.reload$wrap_reload$fn__24791.invoke(reload.clj:39)
at selmer.middleware$wrap_error_page$fn__24806.invoke(middleware.clj:18)
at prone.middleware$wrap_exceptions$fn__25047.invoke(middleware.clj:159)
at ring.middleware.flash$wrap_flash$fn__28337.invoke(flash.clj:39)
at immutant.web.internal.undertow$wrap_undertow_session$fn__39192.invoke(undertow.clj:72)
at ring.middleware.keyword_params$wrap_keyword_params$fn__31059.invoke(keyword_params.clj:53)
at ring.middleware.nested_params$wrap_nested_params$fn__31117.invoke(nested_params.clj:89)
at ring.middleware.multipart_params$wrap_multipart_params$fn__31249.invoke(multipart_params.clj:173)
at ring.middleware.params$wrap_params$fn__31273.invoke(params.clj:67)
at ring.middleware.cookies$wrap_cookies$fn__30892.invoke(cookies.clj:214)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__31411.invoke(absolute_redirects.clj:47)
at ring.middleware.resource$wrap_resource_prefer_resources$fn__31309.invoke(resource.clj:25)
at ring.middleware.content_type$wrap_content_type$fn__31359.invoke(content_type.clj:34)
at ring.middleware.default_charset$wrap_default_charset$fn__31383.invoke(default_charset.clj:31)
at ring.middleware.not_modified$wrap_not_modified$fn__19539.invoke(not_modified.clj:61)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__30560.invoke(x_headers.clj:22)
at myapp.middleware$wrap_internal_error$fn__31485.invoke(middleware.clj:21)
at immutant.web.internal.undertow$create_http_handler$reify__39303.handleRequest(undertow.clj:239)
at org.projectodd.wunderboss.web.undertow.async.websocket.UndertowWebsocket.handleRequest(UndertowWebsocket.java:109)
at io.undertow.server.session.SessionAttachmentHandler.handleRequest(SessionAttachmentHandler.java:68)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:211)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:809)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: clojure.lang.ExceptionInfo: Parameter Mismatch: :username parameter data not found. {}
at hugsql.core$validate_parameters_BANG_.invokeStatic(core.clj:83)
at hugsql.core$validate_parameters_BANG_.invoke(core.clj:69)
at hugsql.core$prepare_sql.invokeStatic(core.clj:185)
at hugsql.core$prepare_sql.invoke(core.clj:173)
at hugsql.core$db_fn_STAR_$y__33452.doInvoke(core.clj:457)
at clojure.lang.RestFn.invoke(RestFn.java:445)
at hugsql.core$db_fn_STAR_$y__33452.invoke(core.clj:448)
at conman.core$try_query$fn__33540$fn__33541.invoke(core.clj:30)
... 45 more
在 db/create-user! 的调用中,在 myapp.routes.home/create-user! 中,我无意中传递了一个额外的参数。当康曼试图用它做点什么时,它就炸开了锅。原文中的代码和解释post。 简短回答:我错误地计算了我的括号。 :/
我也 运行 解决了这个问题,您希望表达式的 return 值与代码块的内容不同。它会产生我所说的 "hanging expression" 问题,并且很容易放错或忽略最后一点代码,尤其是在大型 do
块(或类似 when
、when-not
,等等)。即使使用代码格式化程序(如 IntelliJ IDEA/Cursive),也不容易验证代码对齐和括号位置是否正确。
为了使这样的代码块更易于阅读,我创建了一个超级简单的宏 with-result
in the Tupelo library。实现差不多就是学习宏的"Hello World":
(defmacro with-result
"Evaluates `result` and returns it; also evaluates `forms` for their side-effects."
[result & forms]
`(let [result# ~result]
(do ~@forms)
result#))
使用 with-result
宏,您的代码将变为以下内容:
(ns tst.demo.core
(:require [tupelo.core :as t]))
(defn create-user! [{:keys [params]}]
(if-let [errors (validate-user params)]
; found existing user
(-> (response/found "/users")
(assoc :flash (assoc params :errors errors)))
; need to create new user
(t/with-result (response/found "/users")
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8))))))
你可以看到我添加了简单的评论来帮助衬托 if
的每个分支并总结它的作用。
您还可以选择通过在一个地方调用 (response/found ...)
来进一步简化:
(defn create-user! [{:keys [params]}]
(let [errors (validate-user params)
response (response/found "/users")]
(if errors
(assoc response :flash (assoc params :errors errors))
(t/with-result response
(db/create-user!
(assoc params
:created_at (java.util.Date.)
:updated_at (java.util.Date.)
:pass (generate-password 8)))))))
with-result
对于在离开函数之前打印 return 值也非常方便,或者对于 core.async
代码,其中 core.async
通道必须是 returned在一个大代码块的末尾。