Ruby 및 / 또는 Rails에서 사용자 정의 오류 유형을 정의 할 위치는 어디입니까?


149

Ruby 라이브러리 (gem) 또는 Ruby on Rails 애플리케이션에서 사용자 정의 오류 유형을 정의하는 가장 좋은 방법이 있습니까? 구체적으로 특별히:

  1. 프로젝트에서 구조적으로 어디에 속합니까? 다른 곳에 관련 모듈 / 클래스 정의가있는 별도의 파일?
  2. 때 설정 어떤 규칙이 있는가 하지 않는 새로운 오류 유형을 만들 수는?

라이브러리마다 작업 방식이 다르며 실제 패턴을 보지 못했습니다. 일부 라이브러리는 항상 사용자 정의 오류 유형을 사용하지만 다른 라이브러리는 전혀 사용하지 않습니다. 일부는 StandardError를 확장하는 모든 오류가 있고 다른 일부는 중첩 된 계층이 있습니다. 일부는 빈 클래스 정의이고 다른 일부는 모든 종류의 영리한 트릭을 가지고 있습니다.

아, 그리고이 "오류 유형"이라고 부르는 느낌이 모호하기 때문에, 이것이 의미하는 바는 다음과 같습니다.

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

답변:


219

보석

이런 식으로 예외를 정의하는 것을 여러 번 보았습니다.

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

gem의 경우 예외 파일도 포함해야 할 것 같습니다. github.com/jnunemaker/httparty/blob/… 에서 다시이 예제를보십시오 httparty.
Jason Swett

37
왜 네임 스페이스가 Exceptions모듈에 포함됩니까?
ABMagil 2016 년

13
나는 그것이 /lib오류의 장소가 아닐 수도 있다고 생각 합니다. 그것들은 매우 응용 프로그램마다 다르며 내가 넣은 /lib코드가 다른 응용 프로그램에서 재사용 될 수있는 코드라는 인상을 받고 있습니다.
wuliwong 2016 년

1
Ruby on Rails 지침이 작동하지 않습니다. 일반적인 경우에이 새 파일을 실제로로드하려면 몇 가지 추가 단계가 필요합니까?
Meekohi

1
@ABMagil 내가 달리에있는 것 같다 Unable to autoload constant Exceptions, expected /app/lib/exceptions.rb to define it내가 생각하는 예외 당 하나 개의 클래스가 될 것입니다 다른 옵션
ryan2johnson9

25

프로젝트에 응집력있는 소스 파일을 가지려면 클래스에서 오류를 발생시키고 다른 곳에서는 던질 수없는 오류를 정의해야한다고 생각합니다.

일부 계층 구조는 도움이 될 수 있습니다. 네임 스페이스는 중복 문자열을 유형 이름에서 벗어나는 데 유용하지만 맛이 더 중요합니다. '의도적'과 '우발적'예외 사례 사이.


8
이론적으로는 당신이 옳지 만, 완전히 다른 상황에서 다양한 클래스에 의해 동일한 오류가 발생할 수있을 때 어떻게됩니까?
Alain

1
@Alain 예외 / 오류 모듈에서 둘 이상의 클래스에 의해 사용 된 오류를 정의하지 말고 다른 모든 클래스를 오류를 사용하는 단일 클래스에 정의 해 두십시오.
Scott W

@ScottW,이 경우 개발자는 확인을 기억해야합니다.
Josh Saint Jacque

22

레일에서 app/errors디렉토리 를 만들 수 있습니다

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

스프링 / 서버를 다시 시작하면 픽업해야합니다


이러한 예외를 어떻게 제기해야합니까?
Nikhil Wagh

@NikhilWagh raise FooError, "Example message..."또는raise FooError.new("Example message...")
schpet

13

이것은 오래된 질문이지만 오류 메시지 첨부, 테스트 및 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

여러 사용자 정의 오류 클래스에 대해 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")

그리고 각각의 새로운 에러에 대해 별도의 파일을 원하지 않는다면, 그것들을 모두 넣으십시오lib/app_name/error.rb
jlhonora

얻기 uninitialized constant MyController::AppName. 내 컨트롤러에서 전화를 걸고 있습니다
Nikhil Wagh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.