Rails错误处理;报告,自定义错误

时间:2016-02-21 02:31:04

标签: ruby-on-rails model-view-controller error-handling controller

我正在寻找一种更好的方法来处理错误,我们通常编写接受块的代码,以便在成功的结果中完成。我颠倒了那个想法,并把它写下来:

class SomeVeryBigReportObjectOnWhatWentWrong
   # contains attributes to help format a nice report for humans
   # comes up with a nice backtrace
   # writes to rails log
   # writes to error aggregator (External site)
   # maybe writes to slack depending on error
   # Records the error in another log for developers to view
   # dances and twirls too.
end

class MyTest
  def can?(test, &block)
    return true if test

    if block_given?
      error_report = SomeVeryBigReportObjectOnWhatWentWrong.new("error message for starters")
      yield error_report
    end

    return false
  end
end

class MyController < ApplicationController 

  def action
    page = Page.find(params[:id])
    obj = MyTest.new

    # obj.can?(:read, page)
    return unless obj.can?(false) { | big_error_report |
      big_error_report.context = .... # about 15 lines of this....

      flash[:error] = big_error_report.message
      redirect_to big_error_report.default_error_page
    }

    # back to our regular successful outcomes...

  end
end

此代码的优点是错误处理是缩进的,允许人们轻松查看错误报告的内容,它可以从周围的代码中提取大量上下文,并且可以很好地自定义错误报告。

让下一位程序员的生活更轻松:http://blog.codinghorror.com/the-noble-art-of-maintenance-programming/

代码的缺点是,当我看到它时,我的第一个“思考”是

“返回”,除非“这是假的”?呃?阻止是什么? - 困惑 -

这段代码有异味吗?

1 个答案:

答案 0 :(得分:0)

我的感觉是:

  • 函数can?执行两项操作:检查条件运行测试与否,然后运行一个块。但实际上,您可能只需要其中一个。此外,当你返回false时,你想为这个值做些什么,控制逻辑外部?
  • &block已作为明确参数发送,但我们尚未使用
  • 功能名称不清楚。

如果我重构:(先说清楚)

class MyTest
  def run_report
    if block_given?
      yield SomeVeryBigReportObjectOnWhatWentWrong.new("error message for starters")
    else
      # Handle by default
    end
  end
  def can_report?(test)
   # FIXME: I think you're gonna do something here to proceed test
   test
  end
end

class MyController < ApplicationController 

  def action
    obj = MyTest.new

    if obj.can_report?(false)
      obj.run_report { | big_error_report |
        big_error_report.context = .... # about 15 lines of this....

        flash[:error] = big_error_report.message
        redirect_to big_error_report.default_error_page
      }
      return
    end

    # back to our regular successful outcomes...
  end
end
相关问题