我正在购买我的购物应用,而且我正在尝试创建一个自定义异常处理程序,但是在我找到它们之前还有其他东西可以捕获它们!
这是我的处理程序
(defn wrap-fallback-exception
[handler]
(fn [request]
(try+
(handler request)
(catch [:type :test] {:keys [msg]}
(println "## Test Exception:" msg))
(catch Exception e (println "## Exception"))
(catch Throwable e
(println "## Throwable:" (.getMessage e) e)))))
这是我的堆栈
(-> all-routes
(wrap-anti-forgery)
(friend/authenticate {
:unauthorized-handler unauth-handler
:credential-fn (partial cred get-user)
:workflows [(workflows/interactive-form)]})
(wrap-session {:store (->ShopStore )})
(wrap-keyword-params)
(wrap-params)
(wrap-cookies)
(wrap-fallback-exception)
(run-server {:port 3000}))
我在我的一个戒指函数中进行测试
(throw+ (ex-info "TEST" {:type :test}))
结果输出如下所示
Sun Apr 01 15:57:29 CEST 2018 [worker-4] ERROR - GET /user/home
clojure.lang.ExceptionInfo: TEST {:type :test}
at clojure.core$ex_info.invokeStatic(core.clj:4739)
at clojure.core$ex_info.invoke(core.clj:4739)
at shop2.views.home$mk_proj_row.invokeStatic(home.clj:90)
at shop2.views.home$mk_proj_row.invoke(home.clj:88)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at orchestra.spec.test$spec_checking_fn$fn__1372.doInvoke(test.clj:123)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$map$fn__5587.invoke(core.clj:2747)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:528)
at clojure.core$seq__5124.invokeStatic(core.clj:137)
at clojure.core$print_sequential.invokeStatic(core_print.clj:53)
at clojure.core$fn__7019.invokeStatic(core_print.clj:174)
at clojure.core$fn__7019.invoke(core_print.clj:174)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7039.invokeStatic(core_print.clj:225)
at clojure.core$fn__7039.invoke(core_print.clj:225)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7039.invokeStatic(core_print.clj:225)
at clojure.core$fn__7039.invoke(core_print.clj:225)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7039.invokeStatic(core_print.clj:225)
at clojure.core$fn__7039.invoke(core_print.clj:225)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7019.invokeStatic(core_print.clj:174)
at clojure.core$fn__7019.invoke(core_print.clj:174)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7019.invokeStatic(core_print.clj:174)
at clojure.core$fn__7019.invoke(core_print.clj:174)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.core$print_sequential.invokeStatic(core_print.clj:66)
at clojure.core$fn__7039.invokeStatic(core_print.clj:225)
at clojure.core$fn__7039.invoke(core_print.clj:225)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at clojure.core$pr_on.invokeStatic(core.clj:3666)
at clojure.core$pr_on.invoke(core.clj:3660)
at clojure.lang.Var.invoke(Var.java:385)
at clojure.lang.RT.print(RT.java:1877)
at clojure.lang.RT.printString(RT.java:1857)
at clojure.lang.APersistentVector.toString(APersistentVector.java:26)
at org.httpkit.HttpUtils.bodyBuffer(HttpUtils.java:112)
at org.httpkit.HttpUtils.HttpEncode(HttpUtils.java:442)
at org.httpkit.server.HttpHandler.run(RingHandler.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我的处理程序从未捕获过异常! 我试过没有运气的每个版本:-( 谁在捕捉它? 我怎么让它停下来?
此致 索伦
答案 0 :(得分:1)
您的处理程序成功返回,而不会抛出异常。它返回的值显然是一个多层深度的向量,包含在其自身内部,一个懒惰的序列。当Ring尝试打印该延迟序列时,强制该序列调用mk-proj-row
,这将引发异常。重要的是,这会在您的处理程序完全运行后发生,这意味着异常处理程序不再有效。
我怀疑你真的想要将一个巨型矢量字符串化为你的输出:我猜你忘了使用Hiccup将其转换为HTML,或其他东西将其转换为JSON。您可能应该安装一些中间件,在返回Ring之前进行转换;如果你把那个中间件放在你的wrap-fallback-exception
中间件之前,那么懒惰将不再是一个问题,因为懒惰序列将在Hiccup(或其他)渲染器内实现,而不是在所有处理程序都有结束。