为何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
相关产品推荐
相关产品推荐

