21

通常我需要抛出一个自定义(化)错误。就像由于参数不匹配而无法找到资源时一样。

我更喜欢抛出现有错误,或者抛出从现有错误继承的错误。这样,我就不会介绍已经定义并且可以完美使用的错误类(DRY)。但它也允许保持措辞和风格相同,通过继承和简单地改变一两个词来澄清与原始错误的区别。

例如:

Foo.new
Foo.some_external_id = nil
Foo.fetch_external_resource
# => InvalidOptions: Calling Foo#fetch_external_resource with nil is invalid

我很确定已经定义了此类错误。事实上,在阅读了很多行代码之后,我发现我的 MongoID 驱动程序有Mongoid::Errors::InvalidOptions: Calling Document#find with nil is invalid.

Ruby Core 和 Ruby on Rails 中是否有可用的错误类列表?有没有办法为您当前的项目获取这样的列表?

重用和/或继承现有错误是否明智,或者我应该维护自己的自定义集?

4

3 回答 3

48

虽然这个列表可能会改变,最好仍然使用 Ryan 的解决方案,Rails 4 的列表(仅限于 Rails 类而不是其他 gem):

AbstractController::ActionNotFound
AbstractController::DoubleRenderError
AbstractController::Error
AbstractController::Helpers::ClassMethods::MissingHelperError
ActionController::ActionControllerError
ActionController::BadRequest
ActionController::InvalidAuthenticityToken
ActionController::MethodNotAllowed
ActionController::MissingFile
ActionController::NotImplemented
ActionController::ParameterMissing
ActionController::RedirectBackError
ActionController::RenderError
ActionController::RoutingError
ActionController::SessionOverflowError
ActionController::UnknownController
ActionController::UnknownFormat
ActionController::UnknownHttpMethod
ActionController::UnpermittedParameters
ActionController::UrlGenerationError
ActionDispatch::Cookies::CookieOverflow
ActionDispatch::IllegalStateError
ActionDispatch::Journey::Router::RoutingError
ActionDispatch::ParamsParser::ParseError
ActionDispatch::RemoteIp::IpSpoofAttackError
ActionDispatch::Session::SessionRestoreError
ActionView::Helpers::NumberHelper::InvalidNumberError
ActiveModel::ForbiddenAttributesError
ActiveModel::MissingAttributeError
ActiveRecord::ActiveRecordError
ActiveRecord::AdapterNotFound
ActiveRecord::AdapterNotSpecified
ActiveRecord::AssociationTypeMismatch
ActiveRecord::AttributeAssignmentError
ActiveRecord::ConfigurationError
ActiveRecord::ConnectionNotEstablished
ActiveRecord::ConnectionTimeoutError
ActiveRecord::DangerousAttributeError
ActiveRecord::DeleteRestrictionError
ActiveRecord::DuplicateMigrationNameError
ActiveRecord::DuplicateMigrationVersionError
ActiveRecord::EagerLoadPolymorphicError
ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded
ActiveRecord::HasManyThroughAssociationNotFoundError
ActiveRecord::HasManyThroughAssociationPointlessSourceTypeError
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError
ActiveRecord::HasManyThroughAssociationPolymorphicThroughError
ActiveRecord::HasManyThroughCantAssociateNewRecords
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection
ActiveRecord::HasManyThroughCantDissociateNewRecords
ActiveRecord::HasManyThroughNestedAssociationsAreReadonly
ActiveRecord::HasManyThroughSourceAssociationNotFoundError
ActiveRecord::HasOneThroughCantAssociateThroughCollection
ActiveRecord::IllegalMigrationNameError
ActiveRecord::ImmutableRelation
ActiveRecord::InvalidForeignKey
ActiveRecord::InverseOfAssociationNotFoundError
ActiveRecord::IrreversibleMigration
ActiveRecord::MultiparameterAssignmentErrors
ActiveRecord::NestedAttributes::TooManyRecords
ActiveRecord::PendingMigrationError
ActiveRecord::PreparedStatementInvalid
ActiveRecord::ReadOnlyAssociation
ActiveRecord::ReadOnlyRecord
ActiveRecord::RecordInvalid
ActiveRecord::RecordNotDestroyed
ActiveRecord::RecordNotFound
ActiveRecord::RecordNotSaved
ActiveRecord::RecordNotUnique
ActiveRecord::Rollback
ActiveRecord::SerializationTypeMismatch
ActiveRecord::StaleObjectError
ActiveRecord::StatementInvalid
ActiveRecord::SubclassNotFound
ActiveRecord::Tasks::DatabaseAlreadyExists
ActiveRecord::Tasks::DatabaseNotSupported
ActiveRecord::ThrowResult
ActiveRecord::TransactionIsolationError
ActiveRecord::Transactions::TransactionError
ActiveRecord::UnknownAttributeError
ActiveRecord::UnknownMigrationVersionError
ActiveRecord::UnknownPrimaryKey
ActiveRecord::WrappedDatabaseException
ActiveSupport::JSON::Encoding::CircularReferenceError
ActiveSupport::MessageVerifier::InvalidSignature
ActiveSupport::SafeBuffer::SafeConcatError
ActiveSupport::XMLConverter::DisallowedType
于 2013-10-13T18:31:21.217 回答
27

这里有一个最合适的解决方案:http ://www.ruby-forum.com/topic/158088

由于这个问题没有答案,但出现在 Google 搜索结果的顶部,我决定将 Frederick Cheung 的解决方案包装在一个 rake 任务中并发布在这里。

在lib/tasks/exceptions.rake中删除以下内容

namespace :exceptions do
  task :list => :environment do
    exceptions = []

    ObjectSpace.each_object(Class) do |k|
      exceptions << k if k.ancestors.include?(Exception)
    end

    puts exceptions.sort { |a,b| a.to_s <=> b.to_s }.join("\n")
  end
end

运行它:

bundle exec rake exceptions:list

如果您仍在使用 Rails 2,或者没有使用 Bundler,请不要使用bundle exec

这个列表可能足够了,但并不详尽。例如,ActiveResource 定义了几个异常,例如ActiveResource::ConnectionErrorActiveResource::TimeoutError在我运行此任务时没有出现。也许其他人可以告诉我为什么。

于 2012-01-22T14:56:47.390 回答
8

由于 ActiveSupport,Rails 中提供了一个更短的选项:

puts Exception.descendants.sort_by(&:name)

您还可以查看源代码以了解他们如何处理它。

于 2016-08-23T17:35:34.027 回答