2013-09-16 5 views
4

Как сделать исключение, сделанное ререйзом от bar в последней строке, похоже, что оно произошло оттуда, а не от блока? Я хочу видеть bar в обратном направлении.Re-raise ruby ​​exception from different place

begin 
    raise "foo" 
rescue => e # yeah, i know 
    $e = e # oh boy, globals 
end 

sleep 1 # again, i know 

def bar 
    raise $e 
end 

bar # => test.rb:2:in `<main>': foo (RuntimeError) 

Edit:

Ток трассировку является

test.rb:2:in `<main>': foo (RuntimeError) 

что я хочу (или STH похожа)

test.rb:10:in `bar': foo (RuntimeError) 
from test.rb:13:in `<main>' 
+0

Очень хорошо вопрос, действительно * + 1 * .. –

+3

Что именно вы хотите иметь в backtrace? Просто бар, или оригинальная задняя линия так же хорошо? – BroiSatse

+0

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

ответ

1

Я не уверен, если это то, что вы хотите, но вы можете попробовать:

begin 
    raise "foo" 
rescue => e 
    $e = e 
end 

sleep 1 

def get_full_stack 
    caller 
end 

def bar 
    exception = $e.dup 
    exception.set_backtrace get_full_stack 
    raise exception 
end 
+0

Это работает, заменив 'get_full_stack' на' Kernel.caller'. Благодаря! –

1

Я не уверен, если это правильный ответ. Но я решил дать ей идти :-)

begin 
    raise "foo" 
rescue => e 
    $e = e 
end 

sleep 1 

def bar  
    raise $e.class, "bar" 
end 

bar #=> test.rb:10:in `bar': bar (RuntimeError) 
    from test.rb:13:in `<main>' 

второй попытки

begin 
    ... 
end 

sleep 1 

def bar 
    $e.set_backtrace(["bar"])  
    raise $e 
end 

bar #=> bar: foo (RuntimeError) 
+0

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