2013-04-03 2 views
1

예외가 발생하는 대부분의 경우, 객체에서 메소드를 호출하려고 시도한 결과 객체 주위에서 발생하거나 일부 객체를 실행하는 동안 발생합니다 객체에 속하는 어떤 메소드의 일부인 코드.Ruby 예외가 발생한 객체를 확인하는 방법

주어진 Exception 인스턴스에서이 객체를 어떻게 알 수 있습니까?

예 내 특정 경우

begin 
    .... 
rescue ActiveRecord::SerializationTypeMismatch => e 
    object = e.some_method_which_will_return_active_record_object 
rescue => e 
    object = e.get_me_object_around_which_this_happened 
end 

, 나는 AR 오브젝트 SerializationTypeMismatch가 발생하는 알고 싶어요.

이 경우 e.message 또는 backtrace에 관심이 없기 때문에 e.methods를 확인했지만 관련 객체를 알 수있는 방법을 찾지 못했습니다.

+0

puts e.message는 오류 메시지 –

답변

2

예외가 발생하는 대부분의 경우, 객체에서 메소드를 호출하려는 시도의 결과로 객체 주위에서 발생하거나 일부 메소드의 일부인 일부 코드를 실행하는 동안 발생합니다 객체에 속한다.

는하지만 모든 경우에 사실이 아니다, 그리고 일반적으로 항상 객체가 없을 수 있기 때문에이 발생 "하는 주위에"제기되는 Exception와 객체 사이에 관계가 없다. 예 : LoadError은 필요한 파일 (예 : Ruby 스크립트)을로드하지 못할 때 발생합니다. 그것은 어떤 특정 객체 인스턴스와도 관련이 없습니다. standard exception classes에 대한 이니셜 라이저 메소드가 해당 예외와 관련된 객체를 저장하는 인수를 허용하지 않기 때문에 원래 객체로 다시 매핑하는 직접적인 방법은 없다고 생각합니다.

오류가 발생하는 ActiveRecord 객체로 다시 매핑 할 수없는 경우, begin/rescue 블록이 호출되는 스택에 "너무 높게"배치되어있을 수 있습니다. 예를 들어, 당신은 당신의 begin 블록이 each 루프 같은 것을 할 수 있습니다 : 당신이 오류를 발생하는 항목을 알 수있는 방법이 없습니다 그 시나리오에서

begin 
    items.each do |item| 
    raise RuntimeError unless item == "foo" 
    end 
rescue RuntimeError => e 
    # which item caused the error? 
end 

,하지만 당신은 더 직접 포장하기 위해 begin 블록을 재구성 할 수 코드는 다음과 같이

items.each do |item| 
    begin 
    raise RuntimeError unless item == "foo" 
    rescue RuntimeError => e 
    # the object that raised the exception must be 'item' 
    end 
end 

이것은 물론 인위적인 예입니다, 그러나 희망은 예외를 제기 할 수 코드 주위에 더 밀접하게 begin/rescue 블록 포장의 기술을 보여, 그래서 모호함에 대한이 없다 어떤 물체가 문제를 일으키는 지

+0

을 제공합니다. "시작/복구 블록이"오른쪽 "이라고 불리는 코드 스택에"너무 높게 "배치되어있을 수 있습니다. –

관련 문제