如何正确获取并存储实际返回给用户的HTTP响应状态码?
如何在Rails的after_action中获取实际返回给用户的HTTP状态码?
问题描述
我正在开发一个记录应用特定端点请求的功能,当前实现代码如下:
after_action :record_user_activity def record_user_activity return unless current_user return if request.url =~ /assets|packs/ @session.navigation.create!( uri: request.url, request_method: request.method, response_status: response.code.to_i, access_time: Time.now ) end
但遇到一个问题:即便接口返回了错误响应,after_action钩子中获取的response.code仍然是2xx状态码。推测是服务器在数据访问中遇到的问题还没反映到这个阶段的响应里,请问该如何正确存储实际发送给用户的状态码?
解决方案:改用around_action包裹请求全流程
问题的核心在于:after_action会在异常处理逻辑执行前触发。如果你的错误是通过抛出异常(比如ActiveRecord::RecordNotFound)并由Rails默认异常处理或自定义rescue_from处理的,此时after_action执行时,响应还没被更新为错误状态码,自然拿不到正确的值。
而around_action可以包裹整个请求处理的完整流程——包括action执行、异常捕获与处理、响应最终生成的全部环节。只需要把记录逻辑放在yield之后,就能确保拿到的是实际返回给用户的状态码。
修改后的代码如下:
around_action :record_user_activity def record_user_activity # yield会执行控制器action及后续所有异常处理逻辑 yield return unless current_user return if request.url =~ /assets|packs/ @session.navigation.create!( uri: request.url, request_method: request.method, response_status: response.status, # 直接用response.status获取数字状态码,无需转义 access_time: Time.now ) end
补充说明
response.statusvsresponse.code:response.status本身就是Integer类型的状态码(比如200、404、500),比response.code.to_i更直接,推荐使用。- 验证场景:如果是在action中直接通过
render :status => :bad_request设置错误状态,after_action其实能拿到正确值;但如果是异常触发的错误响应,必须用around_action才能捕获到最终状态。
内容的提问来源于stack exchange,提问作者fizzydrinks
相关产品推荐
相关产品推荐

