在Ruby和/或Rails中定义自定义错误类型的位置?

时间:2011-03-05 00:50:36

标签: ruby-on-rails ruby conventions

在Ruby库(gem)或Ruby on Rails应用程序中定义自定义错误类型是否有最佳实践?具体做法是:

  1. 他们在结构上属于哪个项目?一个单独的文件,内联其他地方的相关模块/类定义?
  2. 是否有任何约定确定何时以及何时创建新的错误类型?
  3. 不同的图书馆有不同的做事方式,我没有注意到任何真实的模式。有些库总是使用自定义错误类型,而有些库根本不使用它们;有些错误扩展了StandardError而其他错误有嵌套层次结构;有些只是空类定义,有些则有各种巧妙的技巧。

    哦,只是因为我觉得称这些“错误类型”有点含糊不清,我的意思是:

    class AuthenticationError < StandardError; end
    class InvalidUsername < AuthenticationError; end
    

5 个答案:

答案 0 :(得分:207)

对于宝石

我已多次看到您以这种方式定义异常:

  

gem_dir / LIB / gem_name / exceptions.rb

并定义为:

module GemName

  class AuthenticationError < StandardError; end
  class InvalidUsername < AuthenticationError; end

end

httparty

中就是这样的一个例子

适用于Ruby on Rails

将它们放在名为exceptions.rb的文件下的lib /文件夹中,它看起来像这样:

module Exceptions
  class AuthenticationError < StandardError; end
  class InvalidUsername < AuthenticationError; end
end

你会像这样使用它:

raise Exceptions::InvalidUsername

答案 1 :(得分:23)

我认为为了在你的项目中拥有有凝聚力的源文件,你应该在类中定义可能抛出错误的错误。

一些层次结构可能会有所帮助 - 命名空间擅长保留冗余字符串的类型名称 - 但这更属于品味 - 如果您在应用中至少有一个自定义异常类型,则无需过分在整个过程中区分“故意”和“意外”异常情况。

答案 2 :(得分:19)

在rails中你可以创建app/errors目录

# app/errors/foo_error.rb
class FooError < StandardError; end

重新启动spring / server,它应该启动它

答案 3 :(得分:8)

为了确保自动加载在Rails 4.1.10中按预期在多个自定义错误类中工作,您需要为每个自定义错误类指定单独的文件。这应该在动态重新加载的开发中工作。

这就是我在最近的项目中设置错误的方法:

lib/app_name/error/base.rb

module AppName
    module Error
        class Base < StandardError; end
    end
end

以及后续的自定义错误,例如lib/app_name/error/bad_stuff.rb

module AppName
    module Error
        class BadStuff < ::AppName::Error::Base; end
    end
end

然后您应该可以通过以下方式调用错误:

 raise AppName::Error::BadStuff.new("Bad stuff just happened")

答案 4 :(得分:8)

这是一个老问题,但我想分享我在Rails中处理自定义错误的方式,包括附加错误消息,测试以及如何使用ActiveRecord模型处理此错误。

创建自定义错误

class MyClass
  # create a custome error
  class MissingRequirement < StandardError; end

  def my_instance_method
    raise MyClass::MissingRequirement, "My error msg" unless true   
  end
end

测试(minitest)

test "should raise MissingRequirement if ____ is missing"
  # should raise an error
  error = assert_raises(MyClass::MissingRequirement) {
    MyClass.new.my_instance_method
  }

  assert error.message = "My error msg"
end

使用ActiveRecord

我认为值得注意的是,如果使用ActiveRecord模型,一种流行的模式是如下所述向模型添加错误,以便验证失败:

def MyModel < ActiveRecord::Base
  validate :code_does_not_contain_hyphens

  def code_does_not_contain_hyphens
    errors.add(:code, "cannot contain hyphens") if code.include?("-")
  end
end

运行验证时,此方法将捎带到ActiveRecord的ActiveRecord::RecordInvalid错误类,并导致验证失败。

希望这有帮助!