2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!请参考 关于页面 了解更多关于这个页面如何工作的信息。

0
core.async

如果一个 go 或 thread 块抛出异常,Clojure 中没有可以捕获和处理(或报告)该异常的内容。相反,它将传播到 ThreadExcecutor,后者调用其 NO-OP afterExecute() 方法,并重新抛出,最终在 System.err 上显示。

{quote}
线程 "async-dispatch-32" 中出现异常 java.lang.IllegalStateException: Fall down, go boom!

at flashiz.resources.orders$index.invoke(orders.clj:26)
at clojure.lang.Var.invoke(Var.java:411)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:617)
at io.aviso.rook$rook_dispatcher.invoke(rook.clj:225)
at flashiz.async$wrap_sync_handler$fn__9005.invoke(async.clj:34)
at flashiz.resources$authorize_async_rook_middleware$fn__9356$fn__9402$state_machine__3245__auto____9403$fn__9405.invoke(resources.clj:21)
at flashiz.resources$authorize_async_rook_middleware$fn__9356$fn__9402$state_machine__3245__auto____9403.invoke(resources.clj:21)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:945)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:949)
at clojure.core.async.impl.ioc_macros$take_BANG_$fn__3261.invoke(ioc_macros.clj:958)
at clojure.core.async.impl.channels.ManyToManyChannel$fn__2256.invoke(channels.clj:80)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

{quote}

如果将 go/thread 块的执行封装在异常处理器中,并委托给默认函数报告异常,那会更令人满意。我的目标是能够修改该函数以更优雅地报告异常并将其写入持久日志文件。

3 个答案

0

由 alexmiller 发表的评论

应用了 ASYNC-76 上的补丁,异常现在将向上传播到线程顶部,在那里它们可以通过标准的 Thread 未捕获异常处理程序机制或最终通过可以为本应用程序设置的默认未捕获异常处理程序捕获。

0

由 whilo 发表的评论

我也多次遇到了这个问题,因此我实现了一个完整的错误处理策略作为 core.async 库: https://github.com/replikativ/superv.async

它有一些限制,例如,在 cljs 中没有跨越异步边界的动态绑定,因此监督器需要按照词法携带,而我更希望有与 Erlang 哲学相符的默认错误处理概念,以便在 core.async 上构建可组合的库。话虽如此,它运行得相当好,应该为您提供安装日志监督器所需的所有必要手段。

0
参考: https://clojure.atlassian.net/browse/ASYNC-61(由 hlewisship 报告)
...