You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ring框架带Coercion的URL参数返回500状态码问题求助

排查Ring应用访问/submissions/:id时的500异常

问题场景

Ring应用中,访问/api/submissions/1时返回500异常,但在REPL中直接调用处理函数(get-submission-by-id {:parameters {:path 20}})运行正常。

应用代码

(def routes
  [["/api"
    ping-routes
    submissions-routes]])

(def app
  (ring/ring-handler
    (ring/router routes
      {:data {:coercion reitit.coercion.schema/coercion
              :muuntaja m/instance
              :middleware [[wrap-cors
                            :access-control-allow-origin [#"http://localhost:4200"]
                            :access-control-allow-methods [:get :post]]
                           parameters-middleware
                           format-negotiate-middleware
                           format-response-middleware
                           exception-middleware
                           format-request-middleware
                           coerce-exceptions-middleware
                           coerce-request-middleware
                           coerce-response-middleware]}})
    (ring/routes
      (ring/redirect-trailing-slash-handler {:method :strip})
      (ring/create-default-handler
       {:not-found (constantly {:status 404 :body "Route not found"})}))))

(def ping-routes
  [["/ping" {:get (fn [req]
                   {:status 200
                    :body {:ping "pong"}})}]])

(def submissions-routes
  [["/submissions"
   ["" {:get get-submissions}]
   ["/:id" {:get {:parameters {:path {:id s/Int}}
                      :handler get-submission-by-id}}]]])

(comment 
  (get-submission-by-id {:parameters {:path 20}}))

错误现象

  • 浏览器访问时返回:{"type":"exception","class":"clojure.lang.ExceptionInfo"}
  • REPL中调用(app {:request-method :get :uri "/api/submissions/1"})返回:
{:status 500,
 :body
 #object[java.io.ByteArrayInputStream 0x3db2e139 "java.io.ByteArrayInputStream@3db2e139"],
 :headers {"Content-Type" "application/json; charset=utf-8"}}

排查步骤

  1. 获取完整异常信息
    ByteArrayInputStream中包含序列化的异常详情,在REPL中执行以下代码解析:

    (slurp (:body (app {:request-method :get :uri "/api/submissions/1"})))
    

    这会输出具体的异常消息,比如参数类型不匹配、coercion失败等核心问题。

  2. 检查参数结构匹配

    • 路由定义中/:id的参数结构是{:parameters {:path {:id s/Int}}},但REPL测试时传入的是{:parameters {:path 20}},两者结构不一致。
    • 验证get-submission-by-id是否正确读取:path下的:id键,而非直接读取:path的值。如果函数期望的是原始数值而非嵌套结构,需要调整参数定义或处理函数逻辑。
  3. 调整中间件顺序
    当前中间件顺序中,exception-middleware放在format-response-middleware之前,会导致异常被格式化后无法正确捕获展示。正确的顺序应将exception-middleware移到最后,确保所有异常都能被捕获并处理:

    :middleware [[wrap-cors
                  :access-control-allow-origin [#"http://localhost:4200"]
                  :access-control-allow-methods [:get :post]]
                 parameters-middleware
                 format-negotiate-middleware
                 format-request-middleware
                 coerce-exceptions-middleware
                 coerce-request-middleware
                 coerce-response-middleware
                 format-response-middleware
                 exception-middleware]
    
  4. 验证依赖与配置

    • 确认已正确引入reitit.coercion.schema依赖
    • 检查muuntaja实例是否正确配置,确保支持JSON的序列化与反序列化

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:42:44