我收到了另一个开发人员工作的项目,但没有留下任何文档。该代码从购物网站获取一些购买,查找价格并通知用户。
该应用可能会遇到“未找到结果”等错误,然后我提出了标准错误。
我想将用户重定向到错误页面并通知他们但是我不能这样做因为它不是控制器,所以redirect_to
选项不起作用。
每小时调用一次services / purchase_checker.rb:
def call
user.transaction do
store_purchase
if better_purchase?
update_purchase
end
end
rescue MyError=> e
store_error(e)
end
def store_error(error)
user.check_errors.create!(error_type: error.class.name, message: error.message)
end
服务/ my_error.rb:
class MyError< StandardError
def initialize(error_type, error_message)
super(error_message)
@error_type = error_type
end
attr_reader :error_type
end
服务/ purchase_fetcher.rb:
def parse_result_page
raise purchase_form_page.error if purchase_form_page.error.present?
offer = purchase_page.map{|proposal_section|
propose(proposal_section, purchase) }
.min_by(&:price)
offer or raise MyError.new("No results", "No results could be found")
end
答案 0 :(得分:1)
你应该创建另一个错误类,例如NotFoundError
:
offer or raise NotFoundError.new("No results", "No results could be found")
然后在你的控制器中:
begin
parse_result_page
rescue NotFoundError => e
redirect_to err_page, :notice => e.message
end
答案 1 :(得分:0)
由于这是在作业中运行,因此通知用户的最佳方式是通过电子邮件或其他一些异步通知方法。检测到错误时,会发送电子邮件。
如果由于某种原因这不是一个选项,您可以检查用户是否在任何相关控制器中有check_errors
。查看发现错误时调用的store_error(error)
方法,它似乎在数据库中创建新记录以记录错误。您应该能够检查用户是否通过user.check_errors
关系记录了任何错误。
你可以这样做,例如:
class SomeController < ActionController::Base
# ...
before_action :redirect_if_check_errors
# ...
def redirect_if_check_errors
# Assuming you're using Devise or something similar
if current_user && current_user.check_errors.exists?
redirect_to some_error_page_you_create_for_this_path
end
end
end
这将检查SomeController
的每个操作中的这些错误,并将用户重定向到您应创建的错误页面,在此处呈现user.check_errors
关系中的错误。
有多种方法可以做到这一点,但我仍然认为如果您想主动通知用户,从Job发送电子邮件是更好的选择。或者可能添加一个界面元素,例如在user.check_errors
有东西的时候警告用户。
答案 2 :(得分:0)
我建议您同步执行此操作,以便响应可以直接在请求/响应周期中发生。也许是这样的:
# controller
def search
# do your searching
# ...
if search_results.blank?
# call model method, but do it synchrously
purchase_check = PurchaseChecker.call
end
if purchase_check.is_a?(MyError) # Check if it's your error
redirect_to(some_path, flash: { warning: "Warn them"})
end
end
# model, say PurchaseChecker
def call
# do your code
rescue MyError => e
store_error(e)
e # return the error so that the controller can do something with it
end