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

在Ruby库(gem)或Ruby on Rails应用程序中定义自定义错误types是否有最佳做法? 特别:

  1. 他们在哪里属于该项目的结构? 一个单独的文件,内嵌相关的模块/类定义,在别的地方?
  2. 是否有任何约定来确定何时和何时创build新的错误types?

不同的图书馆有不同的做事方式,我没有注意到任何真实的模式。 一些库总是使用自定义错误types,而另一些则根本不使用它们; 一些扩展了StandardError的错误,而另一些嵌套了层次结构; 有些只是空的类定义,有些则有各种巧妙的技巧。

哦,只是因为我觉得把这些“错误types”称为模糊的,我的意思是这样的:

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

gem

我已经看到很多次你用这种方式定义exception:

gem_dir / LIB / gem_name / exceptions.rb

并定义为:

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

一个例子就是这样的在httparty中

对于Ruby on Rails

把它们放到你的lib /文件夹下,名为exceptions.rb,看起来像这样:

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

你可以像这样使用它:

 raise Exceptions::InvalidUsername 

我想为了在你的项目中有内聚的源文件,你应该在类中定义错误,在这个错误中可能会抛出他们和别的地方。

一些层次可以是有帮助的 – 命名空间很好地保留types名称中的冗余string – 但这更多的是品味的问题 – 只要在应用程序中至less有一个自定义的exceptiontypes,就不需要太过分了。在“有意”和“偶然”的例外情况之间。

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

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

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") 

在rails中,你可以创buildapp/errors目录

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

重新启动弹簧/服务器,它应该拿起来

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

创build自定义错误

 class MyClass # create a custome error class MissingRequirement < StandardError; end def my_instance_method raise MyClass::MissingRequirement, "My error msg" unless true end end 

testing(最小)

 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模型,一个stream行的模式是向模型添加一个错误,如下所述,以便validation失败:

 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 

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

希望这可以帮助!