我正在尝试在 Lucerne 中构建一个简单的 rest api,但如果 json 格式不正确,clack:call 方法将失败。因此,我扩展了 bass-app 类并添加了一个 around 方法:
(defclass tracker-app (base-app) ()
(:documentation "An extension of lucerne's base app to control behavior"))
(defmethod clack:call :around ((app tracker-app) env)
(handler-case (call-next-method)
(fast-http:cb-message-complete (e)
(vom:error "could not build message body: ~a" e)
(respond nil :status 400))
(:no-error (res) res)))
(defapp server :class 'tracker-app)
(start server :server woo)
但是解析错误继续导致服务器崩溃。
我对 clos 了解不多,所以我担心我误解了如何在这种情况下捕获错误。
编辑:添加启动信息
编辑:添加堆栈跟踪
最佳答案
假设*features*
不包含 :catch-any-error
,这是一个完整的测试用例:
(ql:quickload :lucerne)
(defpackage :so.lucerne (:use :cl :lucerne))
(in-package :so.lucerne)
(defclass tracker-app (base-app) ()
(:documentation "An extension of lucerne's base app to control behavior"))
(defmethod clack:call :around ((app tracker-app) env)
(handler-case (call-next-method)
(fast-http:cb-message-complete (e)
(warn "could not build message body: ~a" e)
(respond nil :status 400))
#+catch-any-error
(error (e) (break "BREAK with ~a" e))
(:no-error (res) res)))
(defmethod clack:call ((app tracker-app) env)
(error "Oh No"))
(defapp server :class 'tracker-app)
(start server :server :woo)
当我尝试加载 localhost:8000
时, 显示以下错误:
Callback Error: the message-complete callback failed
Oh No
[Condition of type FAST-HTTP.ERROR:CB-MESSAGE-COMPLETE]
在 [Condition of type FAST-HTTP.ERROR:CB-MESSAGE-COMPLETE]
上按 Enter给出:
#<FAST-HTTP.ERROR:CB-MESSAGE-COMPLETE {10048315C3}>
--------------------
The object is a CONDITION of type FAST-HTTP.ERROR:CB-MESSAGE-COMPLETE.
FORMAT-CONTROL: NIL
FORMAT-ARGUMENTS: NIL
DESCRIPTION: "the message-complete callback failed"
ERROR: #<SIMPLE-ERROR "Oh No" {1004831583}>
错误包裹了另一个错误。
现在如果我(push :catch-any-error *features*)
并重新编译上面的方法,同样的测试使得代码到达(break ...)
语句,显示为BREAK with Oh No
.
说明
没有fast-http:cb-message-complete
被捕获,实际上此时没有发出这种情况的信号;相反,在这个位置,我们只能捕获发出信号的特定错误。只有在调用堆栈中更高,错误才包含在 fast-http:cb-message-complete
中错误。
解决方案
在您的情况下,您可以直接捕获 jonathan.error:<jonathan-error>
(不寻常的命名约定,但还可以),jonathan
中所有错误的基类库(您可以捕获特定的错误类型,但您可能会遗漏一些其他情况)。
关于json - 如何在 Lucerne 中捕获解析错误(常见的 lisp),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59548546/