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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5200842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:35:32  来源:igfitidea点击:

Where to define custom error types in Ruby and/or Rails?

ruby-on-railsrubyconventions

提问by coreyward

Is there a best practice for defining custom error types in a Ruby library (gem) or Ruby on Rails application? Specifically:

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

  1. Where do they belong structurally in the project? A separate file, inlined with the relevant module/class definition, somewhere else?
  2. Are there any conventions that establish when toand when not tocreate a new error type?
  1. 它们在结构上属于项目的哪个位置?一个单独的文件,与相关的模块/类定义内联,在其他地方?
  2. 有没有建立任何时候约定,当创建一个新的错误类型?

Different libraries have different ways of doing things, and I haven't noticed any real patterns. Some libraries always use custom error types while others don't use them at all; some have all errors extending StandardError while others have nested hierarchies; some are just empty class definitions, others have all sorts of clever tricks.

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

Oh, and just because I feel like calling these "error types" is sort of ambiguous, what I mean is this:

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

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

回答by Mike Lewis

For Gems

对于宝石

I have seen many times that you define exceptions in this way:

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

gem_dir/lib/gem_name/exceptions.rb

gem_dir/lib/gem_name/exceptions.rb

and defined as:

并定义为:

module GemName

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

end

an example of this would be something like this in httparty

这方面的一个例子在httparty 中是这样的

For Ruby on Rails

对于 Ruby on Rails

Put them in your lib/ folder under a file called exceptions.rb, which would look something like this:

将它们放在 lib/ 文件夹中名为 exceptions.rb 的文件下,该文件如下所示:

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

and you would use it like this:

你会像这样使用它:

raise Exceptions::InvalidUsername

回答by Dean Radcliffe

I think in order to have cohesive source files in your project, you should define errors in the class in which may throw them and nowhere else.

我认为为了在您的项目中拥有有凝聚力的源文件,您应该在可能抛出它们的类中定义错误而不是其他地方。

Some heirarchy can be helpful - namespaces are good at keeping redundant strings out of type names - but that's more a matter of taste - there's no need to go overboard provided you have at least one custom exception type in your app which you use throughout to differentiate between 'intentional' and 'accidental' exception cases.

一些层次结构可能会有所帮助 - 命名空间擅长将多余的字符串排除在类型名称之外 - 但这更多是一种品味问题 - 如果您的应用程序中至少有一个自定义异常类型,您就可以使用它来区分介于“故意”和“意外”例外情况之间。

回答by schpet

in rails you can make app/errorsdirectory

在 Rails 中,您可以创建app/errors目录

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

restart spring/server and it should pick it up

重新启动 spring/server 并且它应该可以启动它

回答by Matt

This is an old question, but I wanted to share how I'm handling custom errors in Rails, including attaching error messages, testing, and how to handle this with ActiveRecordmodels.

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

Creating Custom Error

创建自定义错误

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 (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

With ActiveRecord

使用 ActiveRecord

I think it's worth noting that if working with an ActiveRecordmodel, a popular pattern is to add an error to the model as described below, so that your validations will fail:

我认为值得注意的是,如果使用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

When validations are run, this method will piggy-back onto ActiveRecord's ActiveRecord::RecordInvaliderror class and will cause validations to fail.

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

Hope this helps!

希望这可以帮助!

回答by spyle

To ensure that autoloading works as expected in Rails 4.1.10 for multiple custom error classes, you'll want to specify separate files for each. This should work in development with its dynamically reloading.

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

This is how I setup errors in a recent project:

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

In lib/app_name/error/base.rb

lib/app_name/error/base.rb

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

and in subsequent custom errors, like in lib/app_name/error/bad_stuff.rb

并在随后的自定义错误中,例如 lib/app_name/error/bad_stuff.rb

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

You should then be able to call your errors via:

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

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