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

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

  1. 它们在结构上属于项目的什么地方? 一个单独的文件,内联了相关的模块/类定义,还是其他地方?
  2. 不要创建一个新的错误类型时,是否有任何约定?

不同的库有不同的工作方式,我还没有注意到任何真正的模式。一些库总是使用自定义错误类型,而另一些库根本不使用它们; 一些库在扩展 StandardError 时出现所有错误,而另一些库具有嵌套的层次结构; 一些库只是空的类定义,其他库有各种聪明的技巧。

哦,正因为我觉得称呼这些“错误类型”有点模棱两可,我的意思是:

class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end
65206 次浏览

我认为,为了在您的项目中拥有内聚的源文件,您应该在类中定义可能抛出错误的错误,而不是其他任何错误。

一些层次结构是有帮助的——名称空间能够很好地防止类型名称中出现多余的字符串——但这更多的是一个品味问题——如果你的应用程序中至少有一个自定义的异常类型,你可以一直使用它来区分“有意的”和“偶然的”异常情况,那么你就没有必要做得太过火。

为了宝石

我已经看到过很多次这样定义异常:

Gem _ dir/lib/gem _ name/exctions.rb

定义为:

module GemName


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


end

这样的例子在 httparty中是这样的

Ruby on Rails

将它们放在 lib/文件夹中名为 exctions.rb 的文件下,该文件类似于下面的内容:

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

你可以这样使用它:

raise Exceptions::InvalidUsername

为了确保自动加载能够在 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")

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

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

重新启动 spring/server,它应该会接收到

这是一个老问题,但我想分享我如何在 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

测试(最小)

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错误类上,并导致验证失败。

希望这个能帮上忙!