Где определить пользовательские типы ошибок в Ruby и / или Rails? - PullRequest
140 голосов
/ 05 марта 2011

Есть ли лучшая практика для определения пользовательских типов ошибок в библиотеке Ruby (gem) или приложении Ruby on Rails?В частности:

  1. К чему они относятся структурно в проекте?Отдельный файл с указанием соответствующего модуля / определения класса где-нибудь еще?
  2. Существуют ли соглашения, которые устанавливают, когда до и когда не до , создают новую ошибкуtype?

В разных библиотеках разные способы работы, и я не заметил никаких реальных шаблонов.Некоторые библиотеки всегда используют пользовательские типы ошибок, в то время как другие не используют их вообще;у некоторых есть все ошибки, расширяющие StandardError, в то время как у других есть вложенные иерархии;некоторые из них являются просто пустыми определениями классов, другие имеют всевозможные хитрые уловки.

О, и просто потому, что я чувствую, что называть эти «типы ошибок», довольно двусмысленно, я имею в виду следующее:1016 *

Ответы [ 5 ]

210 голосов
/ 20 марта 2011

Для драгоценных камней

Я много раз видел, как вы определяете исключения таким образом:

gem_dir / lib / gem_name / exceptions.rb

и определяется как:

module GemName

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

end

Примером этого может быть что-то вроде этого в httparty

Для Ruby on Rails

Поместите их в свою папку lib / в файл с именем exceptions.rb, который будет выглядеть примерно так:

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

, и вы будете использовать его так:

raise Exceptions::InvalidUsername
24 голосов
/ 20 марта 2011

Я думаю, что для того, чтобы иметь согласованные исходные файлы в вашем проекте, вы должны определить ошибки в классе, в которые они могут быть брошены и нигде больше.

Некоторая иерархия может быть полезной - пространства имен хороши для того, чтобы не допускать избыточных строк в именах типов - но это скорее дело вкуса - не нужно переусердствовать, если в вашем приложении есть хотя бы один пользовательский тип исключения, который вы используете повсюду, чтобы провести различие между «преднамеренными» и «случайными» исключительными случаями.

19 голосов
/ 11 мая 2017

в рельсах вы можете сделать app/errors каталог

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

перезапустить spring / server и он должен забрать его

8 голосов
/ 04 ноября 2017

Это старый вопрос, но я хотел поделиться с вами тем, как я обрабатываю пользовательские ошибки в 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::RecordInvalid ActiveRecord и приводит к сбою проверок.

Надеюсь, это поможет!

8 голосов
/ 24 сентября 2015

Чтобы обеспечить правильную работу автозагрузки в 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...