루비가 잘린 것이 아니라 전체 역 추적을 인쇄하도록하려면 어떻게해야합니까?
예외가 발생하면 종종 호출 스택 내부에서 발생합니다. 이런 일이 발생하는 경우, 종종 실제 코드 위반이 숨겨집니다.
tmp.rb:7:in `t': undefined method `bar' for nil:NilClass (NoMethodError)
from tmp.rb:10:in `s'
from tmp.rb:13:in `r'
from tmp.rb:16:in `q'
from tmp.rb:19:in `p'
from tmp.rb:22:in `o'
from tmp.rb:25:in `n'
from tmp.rb:28:in `m'
from tmp.rb:31:in `l'
... 8 levels...
from tmp.rb:58:in `c'
from tmp.rb:61:in `b'
from tmp.rb:64:in `a'
from tmp.rb:67
"... 8 레벨 ..."잘림으로 인해 많은 문제가 발생했습니다. 나는 이것에 대한 인터넷 검색에별로 성공하지 못했습니다. 루비에게 덤프에 전체 스택을 포함시키고 싶다고 어떻게 말합니까?
예외 # backtrace에는 전체 스택이 있습니다.
def do_division_by_zero
x = 5 / 0
end
begin
do_division_by_zero
rescue => Exception
puts Exception.backtrace
raise # always reraise
end
(Peter Cooper의 Ruby Inside 블로그 에서 영감을 받음 )
간단한 원 라이너를 원한다면이 작업을 수행 할 수도 있습니다.
puts caller
이렇게하면 오류 설명과 깔끔하고 들여 쓰기 된 스택 추적이 생성됩니다.
begin
# Some exception throwing code
rescue => e
puts "Error during processing: #{$!}"
puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
end
IRB에는이 끔찍한 "기능"에 대한 설정이 있으며이를 사용자 지정할 수 있습니다.
~/.irbrc
다음 행을 포함 하는 파일을 작성하십시오 .
IRB.conf[:BACK_TRACE_LIMIT] = 100
이를 통해 irb
적어도 100 개의 스택 프레임을 볼 수 있습니다 . 비 대화식 런타임에 해당하는 설정을 찾을 수 없습니다.
IRB 사용자 정의에 대한 자세한 정보는 Pickaxe 서적 에서 찾을 수 있습니다 .
콜 스택을위한 하나의 라이너 :
begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace; end
모든 보석이없는 콜스 택용 라이너 :
begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace.grep_v(/\/gems\//); end
모든 gem이없고 현재 디렉토리에 상대적인 콜 스택을위한 하나의 라이너
begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace.grep_v(/\/gems\//).map { |l| l.gsub(`pwd`.strip + '/', '') }; end
중요한 루비 추적을 모방합니다.
begin
0/0 # or some other nonsense
rescue => e
puts e.backtrace.join("\n\t")
.sub("\n\t", ": #{e}#{e.class ? " (#{e.class})" : ''}\n\t")
end
흥미롭게도 '처리되지 않은 예외'를 올바르게 처리하지 않아 'RuntimeError'로보고되지만 위치는 정확합니다.
I was getting these errors when trying to load my test environment (via rake test or autotest) and the IRB suggestions didn't help. I ended up wrapping my entire test/test_helper.rb in a begin/rescue block and that fixed things up.
begin
class ActiveSupport::TestCase
#awesome stuff
end
rescue => e
puts e.backtrace
end
[examine all threads backtraces to find the culprit]
Even fully expanded call stack can still hide the actual offending line of code from you when you use more than one thread!
Example: One thread is iterating ruby Hash, other thread is trying to modify it. BOOM! Exception! And the problem with the stack trace you get while trying to modify 'busy' hash is that it shows you chain of functions down to the place where you're trying to modify hash, but it does NOT show who's currently iterating it in parallel (who owns it)! Here's the way to figure that out by printing stack trace for ALL currently running threads. Here's how you do this:
# This solution was found in comment by @thedarkone on https://github.com/rails/rails/issues/24627
rescue Object => boom
thread_count = 0
Thread.list.each do |t|
thread_count += 1
err_msg += "--- thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace begin \n"
# Lets see if we are able to pin down the culprit
# by collecting backtrace for all existing threads:
err_msg += t.backtrace.join("\n")
err_msg += "\n---thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace end \n"
end
# and just print it somewhere you like:
$stderr.puts(err_msg)
raise # always reraise
end
The above code snippet is useful even just for educational purposes as it can show you (like x-ray) how many threads you actually have (versus how many you thought you have - quite often those two are different numbers ;)
You can also use backtrace Ruby gem (I'm the author):
require 'backtrace'
begin
# do something dangerous
rescue StandardError => e
puts Backtrace.new(e)
end
'programing tip' 카테고리의 다른 글
Enum에서 문자열을 검색하고 Enum을 반환 (0) | 2020.06.13 |
---|---|
CryptographicException '키셋이 없습니다', 그러나 WCF를 통해서만 (0) | 2020.06.12 |
CSS로 사각형 이미지를 사각형으로“자르는”방법은 무엇입니까? (0) | 2020.06.12 |
크기가 0 인 Linux 삭제 파일 (0) | 2020.06.12 |
좋아하는 (영리한) 방어 프로그래밍 모범 사례 (0) | 2020.06.12 |