Ruby on rails Rails错误处理;报告、自定义错误

Ruby on rails Rails错误处理;报告、自定义错误,ruby-on-rails,model-view-controller,error-handling,controller,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 erro

我正在寻找一种更好的方法来处理错误,我们通常会编写代码,接受在成功的情况下完成的块。我颠倒了这个想法,写下了这样的话:

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
将SomeveryBigReportObjectOnWhattwenthouse类
#包含有助于为人类设置良好报告格式的属性
#提出了一个很好的回溯
#写入rails日志
#写入错误聚合器(外部站点)
#可能会写入slack,具体取决于错误
#将错误记录在另一个日志中,供开发人员查看
#跳舞和旋转。
结束
类MyTest
def can?(测试和阻塞)
如果测试失败,则返回true
如果给出了block_?
error\u report=someveryBigReportObjectOnWhatwentError.new(“针对初学者的错误消息”)
产量误差报告
结束
返回错误
结束
结束
类MyController
这段代码的优点是错误处理是缩进的,允许人们很容易地看到什么是错误报告,它可以从周围的代码中提取大量上下文,并且可以很好地自定义错误报告

让下一个程序员的生活更轻松:

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

“返回”,除非“这是假的”?UH这个街区是干什么的迷茫-

这个代码有味道吗

我的感觉是:

  • 函数
    can?
    做两件事:检查条件是否运行测试并运行块。但实际上,您可能只需要其中一个。此外,当您返回
    false
    时,您想对该值做什么,控制外部逻辑
  • &block
    已作为显式参数发送,但我们尚未使用它
  • 函数名不清楚
如果我重构这个:(先弄清楚)

classmytest
def运行报告
如果给出了block_?
生成SomeveryBigReportObjectOnWhatwentError.new(“针对初学者的错误消息”)
其他的
#默认处理
结束
结束
def can_报告?(测试)
#我想你应该做点什么来继续测试
测试
结束
结束
类MyController
这个代码在整个网站上经常出现,这就是我将这两个功能结合在一起的原因。我可以看到可读性的提高。
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