Rails 5 API如何处理数据库连接异常并向用户友好返回自定义响应
Rails 5 API SQLite3 数据库连通性异常自定义处理方案
实现步骤
1. 控制器层全局异常捕获
在app/controllers/application_controller.rb中添加全局异常捕获规则,覆盖所有数据库相关异常,根据请求格式返回对应响应:
class ApplicationController < ActionController::API # 捕获所有数据库连通性、迁移相关异常 rescue_from ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished, ActiveRecord::StatementInvalid, ActiveRecord::MigrationError, SQLite3::CantOpenException, with: :handle_database_unavailable private def handle_database_unavailable(exception) error_msg = "数据库服务当前不可用,请稍后重试" # 可根据需要自定义不同异常的返回提示 respond_to do |format| format.json { render json: { error: error_msg }, status: :service_unavailable } format.text { render plain: error_msg, status: :service_unavailable } format.all { render plain: error_msg, status: :service_unavailable } end end end
各异常对应场景:
ActiveRecord::NoDatabaseError:数据库文件不存在ActiveRecord::ConnectionNotEstablished:数据库连接无法建立ActiveRecord::MigrationError:存在未执行的待处理迁移SQLite3::CantOpenException:SQLite3驱动层面无法打开数据库文件ActiveRecord::StatementInvalid:数据库连接异常时执行SQL触发的错误
2. 中间件层异常兜底捕获
部分数据库异常(如待处理迁移报错)会在请求进入控制器前的中间件层抛出,无法被控制器的rescue_from捕获,需要配置全局异常兜底处理:
2.1 修改应用全局配置
编辑config/application.rb,指定自定义异常处理路由:
module YourAppName # 替换为你的实际应用命名空间 class Application < Rails::Application # 保留原有配置,新增以下内容 config.exceptions_app = self.routes # 开发环境测试时可开启以下配置,关闭默认调试错误页,生产环境默认无需配置 # config.consider_all_requests_local = false end end
2.2 新增异常响应路由
编辑config/routes.rb,添加异常状态码匹配路由:
Rails.application.routes.draw do # 保留原有业务路由,新增以下兜底路由 match "/503", to: "errors#service_unavailable", via: :all match "/500", to: "errors#service_unavailable", via: :all end
2.3 新增错误处理控制器
新建app/controllers/errors_controller.rb实现异常响应逻辑:
class ErrorsController < ApplicationController def service_unavailable error_msg = "数据库服务当前不可用,请稍后重试" respond_to do |format| format.json { render json: { error: error_msg }, status: :service_unavailable } format.text { render plain: error_msg, status: :service_unavailable } end end end
3. 效果验证
- 删除数据库文件
rm db/development.sqlite3后发起请求,确认返回自定义响应而非默认报错 - 修改
config/database.yml中的数据库文件名指向不存在的路径,重启服务后发起请求,确认返回自定义响应 - 新增迁移后不执行
rails db:migrate,发起请求确认不会返回默认的待处理迁移报错
内容的提问来源于stack exchange,提问作者Hussain Niazi
相关产品推荐
相关产品推荐

