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

为何Rails 6中间件的rescue块无法捕获PG::ConnectionBad异常?

捕获PG::ConnectionBad异常的Rails中间件问题及解决方案

我在开发Rails 6应用时,自定义了PGConnectionErrorMiddleware中间件,目的是捕获PG::ConnectionBad异常并返回自定义的503响应,但该中间件未按预期工作——当PG::ConnectionBad异常抛出时,rescue块并未捕获到异常,应用直接返回500错误。

原中间件代码

class PGConnectionErrorMiddleware
    def initialize(app)
      @app = app
    end
  
    def call(env)
      puts "PGConnectionErrorMiddleware called!" 
      status, headers, response = @app.call(env)
      puts "Status code: #{status}"
      puts "Headers: #{headers.inspect}"
      [status, headers, response]
    rescue => e
      Rails.logger.error "PG::ConnectionBad: #{e.message}"
      puts "PG::ConnectionBad>>: #{e.message}"
      [503, { 'Content-Type' => 'text/html' }, [File.read(Rails.public_path.join('503.html'))]]
    end
  end

异常发生时的日志片段

PGConnectionErrorMiddleware called!
Started GET "/sign_in" for 172.19.0.1 at 2023-02-26 20:27:51 +0000
PGConnectionErrorMiddleware called!
Started GET "/tour" for 172.19.0.1 at 2023-02-26 20:28:10 +0000
  
PG::ConnectionBad (could not translate host name "postgresql" to address: Name or service not known
):
  
lib/pg_connection_error_middleware.rb:8:in `call'
Status code: 500
Headers: {"Content-Type"=>"text/html; charset=UTF-8", "Content-Length"=>"728", "X-Request-Id"=>"03b35a89-1de9-4d82-a5ab-039b5fe45ef1", "X-Runtime"=>"18.744346"}
  
PG::ConnectionBad (could not translate host name "postgresql" to address: Name or service not known
):
  
lib/pg_connection_error_middleware.rb:8:in `call'
Status code: 500
Headers: {"Content-Type"=>"text/html; charset=UTF-8", "Content-Length"=>"728", "X-Request-Id"=>"fb4be3c4-5d8e-4503-980c-73a898d96933", "X-Runtime"=>"67.208042"}

从日志可见,中间件已被调用,但异常未被rescue块捕获,最终返回500错误。

解决方案

通过修改中间件代码,提前触发数据库连接检查,同时精准捕获PG::ConnectionBad异常,成功实现了预期功能:

class PGConnectionErrorMiddleware
    def initialize(app)
      @app = app
    end
  
    def call(env)
      begin
        ActiveRecord::Base.connection
        @app.call(env)
      rescue PG::ConnectionBad => e
        Rails.logger.error "PG::ConnectionBad: #{e.message}"
        [503, { 'Content-Type' => 'text/html' }, [File.read(Rails.public_path.join('503.html'))]]
      end
    end
end

内容的提问来源于stack exchange,提问作者Y.H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:28:09