web-dev-qa-db-ja.com

Rubyおよび/またはRailsでカスタムエラータイプを定義する場所は?

Rubyライブラリ(gem)またはRuby on Railsアプリケーション?具体的には:

  1. 彼らはプロジェクトのどこに構造的に属しますか?関連するモジュール/クラス定義でインライン化された別のファイル、どこか?
  2. toおよびnot toの場合に新しいエラータイプを作成する規則はありますか?

さまざまなライブラリにはさまざまな方法がありますが、実際のパターンに気付いたことはありません。一部のライブラリでは常にカスタムエラータイプが使用されますが、他のライブラリではまったく使用されません。 StandardErrorを拡張するすべてのエラーを持つものもあれば、ネストされた階層を持つものもあります。空のクラス定義であるものもあれば、あらゆる種類の巧妙なトリックがあるものもあります。

ああ、私はこれらの「エラータイプ」と呼ぶのがちょっと曖昧だと思うからといって、これは私が言っていることです:

class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end
140
coreyward

宝石の場合

この方法で例外を定義することを何度も見てきました。

gem_dir/lib/gem_name/exceptions.rb

そして次のように定義されます:

module GemName

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

end

この例は httparty のようなものです

For Ruby on Rails

それらをlibsフォルダーのexceptions.rbというファイルの下に置きます。これは次のようになります。

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

次のように使用します。

raise Exceptions::InvalidUsername
212
Mike Lewis

プロジェクト内にまとまりのあるソースファイルを作成するには、クラス内でエラーを定義する必要があります。

いくつかの階層が役立つ場合があります-名前空間は冗長な文字列を型名から除外するのに優れています-しかし、それは好みの問題です-差別化のために全体で使用するアプリ内に少なくとも1つのカスタム例外タイプがある場合、過剰に行く必要はありません「意図的な」例外ケースと「偶発的な」例外ケースの間。

24
Dean Radcliffe

in Railsを作成できますapp/errorsディレクトリ

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

spring/Serverを再起動すると、それが拾われるはず

21
schpet

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

これは古い質問ですが、エラーメッセージの添付、テスト、ActiveRecordモデルでこれを処理する方法など、Railsでカスタムエラーを処理する方法を共有したかったのです。

カスタムエラーの作成

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エラークラス。検証が失敗します。

お役に立てれば!

9
Matt