[英]Can I put retry in rescue block without begin ... end?
我遇到了一個問題,當 PG 不同步時(眾所周知的問題)( 示例)。
PG 不同步失敗,id 序列停止遞增並引發ActiveRecord::RecordNotUnique
錯誤。
但是這里提出的所有解決方案(我找到的所有解決方案)都提出了一些手動解決方案 - 要么在控制台中進行一些操作,要么運行自定義 rake 任務。
然而,我發現這對生產來說並不令人滿意:每次發生這種情況時,用戶都會得到 500,而管理服務器的人應該可以節省一天的時間。 (並且根據出於某種原因的測試數據,在我的情況下可能會經常發生)。
所以我寧願修補 ActiveRecord 基類來捕捉這個特定的錯誤並拯救它。
我有時在控制器中使用這個邏輯:
class ApplicationController < ActionController::Base
rescue_from ActionController::ParameterMissing, ActiveRecord::RecordNotFound do |e|
# some logic here
end
end
但是,在這里我不需要重試。 另外,我不想深入研究猴子補丁,例如,不覆蓋 Base 創建方法。
所以我在想這樣的事情:
module ActiveRecord
class Base
rescue ActiveRecord::RecordNotUnique => e
if e.message.include? '_pkey'
table =e.message.match(//) #regex to define table
ActiveRecord::Base.connection.reset_pk_sequence!(table)
retry
else
raise
end
end
end
但它很可能不起作用,因為我不確定 Rails/Ruby 是否會理解它究竟要求重試什么。
有什么解決辦法嗎?
PS 對於整個序列問題的非相關解決方案,在沒有手動命令行命令的情況下也可以工作並且沒有服務的用戶也很受歡迎。
要回答你問的問題,不。 rescue
只能在begin..end
塊或方法體中使用。
begin
bad_method
rescue SomeException
retry
end
def some_method
bad_method
rescue SomeException
retry
end
由於在控制器中執行的間接性, rescue_from
只是一個框架輔助方法。
要回答你真正問的問題,當然。 您可以使用rescue
/ retry
覆蓋create_or_update
。
module NonUniquePkeyRecovery
def create_or_update(*)
super
rescue ActiveRecord::RecordNotUnique => e
raise unless e.message.include? '_pkey'
self.class.connection.reset_pk_sequence!(self.class.table_name)
retry
end
end
ActiveSupport.on_load(:active_record) do
include NonUniquePkeyRecovery
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.