web-dev-qa-db-fra.com

Où définir les types d'erreur personnalisés dans Ruby et / ou Rails?

Existe-t-il une bonne pratique pour définir des types d’erreur personnalisés dans une bibliothèque Ruby (gem)] ou Ruby sur Rails??? Plus précisément:

  1. Où appartiennent-ils structurellement dans le projet? Un fichier séparé, intégré à la définition de module/classe appropriée, ailleurs?
  2. Existe-t-il des conventions qui établissent quand to et when not to créer un nouveau type d'erreur?

Différentes bibliothèques ont différentes façons de faire les choses et je n'ai remarqué aucune tendance réelle. Certaines bibliothèques utilisent toujours des types d'erreur personnalisés alors que d'autres ne les utilisent pas du tout. certaines ont toutes des erreurs lors de l'extension de StandardError alors que d'autres ont des hiérarchies imbriquées; certaines ne sont que des définitions de classe vides, d'autres ont toutes sortes d'astuces intelligentes.

Oh, et juste parce que j'ai envie d'appeler ces "types d'erreur", c'est un peu ambigu, ce que je veux dire, c'est ceci:

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

Pour les pierres précieuses

J'ai vu maintes fois que vous définissez les exceptions de cette manière:

gem_dir/lib/gem_name/exceptions.rb

et défini comme:

module GemName

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

end

un exemple de ceci serait quelque chose comme ceci dans httparty

Pour Ruby sur Rails

Placez-les dans votre dossier lib/sous un fichier appelé exceptions.rb, qui ressemblerait à ceci:

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

et vous l'utiliseriez comme ceci:

raise Exceptions::InvalidUsername
212
Mike Lewis

dans Rails vous pouvez faire app/errors répertoire

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

redémarrer printemps/serveur et il devrait le ramasser

21
schpet

Pour vous assurer que le chargement automatique fonctionne comme prévu dans Rails 4.1.10 pour plusieurs classes d'erreur personnalisées, vous voudrez spécifier des fichiers distincts pour chaque fichier. Cela devrait fonctionner en développement avec son rechargement dynamique.

Voici comment configurer les erreurs dans un projet récent:

Dans lib/app_name/error/base.rb

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

et dans les erreurs personnalisées suivantes, comme dans lib/app_name/error/bad_stuff.rb

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

Vous devriez alors pouvoir appeler vos erreurs via:

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

C'est une vieille question, mais je souhaitais expliquer comment je gère les erreurs personnalisées dans Rails, notamment en joignant des messages d'erreur, en effectuant des tests, et comment gérer cela avec les modèles ActiveRecord.

Créer une erreur personnalisée

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

Avec ActiveRecord

Je pense que cela vaut la peine de noter que si vous travaillez avec un modèle ActiveRecord, un modèle courant consiste à ajouter une erreur au modèle, comme décrit ci-dessous, afin que vos validations échouent:

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

Lorsque les validations sont exécutées, cette méthode se greffe sur la classe d'erreur ActiveRecord::RecordInvalid D'ActiveRecord et entraîne l'échec des validations.

J'espère que cela t'aides!

9
Matt