2014-10-05 2 views
4
context = V8::Context.new(timeout: 20000) do |context| 
    context['ForbidAccess'] = ->(message) { throw NotImplementedError } 
end 

begin 
    context.eval("ForbidAccess();") 
rescue => e 
    puts "e.class = #{e.class.name}" 
    puts "e.causes = #{e.causes}" 
    puts "e.root_cause = #{e.root_cause}" 
    puts "e.root_cause.class = #{e.root_cause.class}" 
end 

콘솔 출력을 루비 예외가?V8 컨텍스트에서

+0

귀하의 질문을 올바르게 읽고 싶다면 Ruby 코드에서 JavaScript 예외에 액세스하는 방법은 무엇입니까? – Doon

+0

'raise'대신 'throw'를 사용했습니다. 그게 다야. – Jacob

답변

2

당신은 아마 당신이하고있는 생각하고 있지 않습니다 (NotImplementedError 그냥 쇼를위한 것입니다. 그것은 등 메시지를 포함하는 사용자 정의 예외로 대체 얻을 것이다). throw 키워드는 예외가 아닙니다. 그것은 실제로 다른 언어에서 goto와 유사한 로컬 점프입니다. 이 발췌 부분을 참조하십시오 :

"잡힌"객체가 "던져진"객체와 일치해야하는 것은 제어 흐름 구조입니다. 그러나 모든 던지기를 잡아서 어떤 물체인지 파악할 수는 없습니다.

context = V8::Context.new(timeout: 20000) do |context| 
    context['ForbidAccess'] = ->(message) { raise NotImplementedError } 
end 

begin 
    context.eval("ForbidAccess();") 
rescue => e 
    puts "e.root_cause = #{e.root_cause.inspect}" 
    # correctly prints #<NotImplementedError: NotImplementedError> 
end 

당신이 거기 ArgumentError를 볼 이유에 관해서는, 그것은 간단하다 : - 예외에서 구출 rescue 구조 (A 던져는 begin을 통해 얻을 수없는 예외 (NotImplementedError를 같은)를 사용하는 올바른 것은 raise입니다 들어). 잡히지 않은 던지기가 구조를 만났을 때 새로운 예외가 생성됩니다. 아래의 확인 :

begin 
    throw "whatever" 
rescue e 
    p e #=> ArgumentError: uncaught throw "whatever" 
end 

internally 일어나는 모든 V8 라이브러리 참조가 팝업 ArgumentError입니다 것입니다.

+0

루비의 레이즈와 자바 스크립트의 포기에 대해 알고 있지만 분명히 완전히 깨어나지 않았습니다. 그것을 지적 해 주셔서 대단히 감사합니다. 또한 루비가 몇 년 전에 C#을 쓰는 데 도움이되지 않습니다. 루비는 자바 스크립트로 'throw'를 사용합니다. – Jacob