programing

잘린 역추적 대신 전체 역추적을 인쇄하려면 어떻게 해야 합니까?

newstyles 2023. 6. 23. 21:48

잘린 역추적 대신 전체 역추적을 인쇄하려면 어떻게 해야 합니까?

예외가 발생하면 콜 스택 내부에서 발생하는 경우가 많습니다.이런 일이 발생할 때, 대부분의 경우 실제 위반 코드는 나에게 숨겨져 있습니다.

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; 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

이렇게 하면 100개의 스택 프레임을 볼 수 있습니다.irb,적어도.대화형이 아닌 런타임에 대한 동일한 설정을 찾을 수 없습니다.

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

재미있게도 'unhandled exception'을 제대로 처리하지 못하고 'Runtime Error'로 보고하는데, 위치가 맞습니다.

거의 모든 사람들이 이것에 대답했습니다.레일 예외를 로그에 인쇄하는 제 버전은 다음과 같습니다.

begin
    some_statement
rescue => e
    puts "Exception Occurred #{e}. Message: #{e.message}. Backtrace:  \n #{e.backtrace.join("\n")}"
    Rails.logger.error "Exception Occurred #{e}. Message: #{e.message}. Backtrace:  \n #{e.backtrace.join("\n")}"
end

Rake 테스트 또는 자동 테스트를 통해 테스트 환경을 로드하려고 할 때 이러한 오류가 발생했지만 IRB 제안이 도움이 되지 않았습니다.저는 결국 전체 test/test_helper.rb를 begin/rescue 블록으로 포장하여 문제를 해결했습니다.

begin
  class ActiveSupport::TestCase
    #awesome stuff
  end
rescue => e
  puts e.backtrace
end

[범인을 찾기 위해 모든 역추적 스레드를 조사합니다]
완전히 확장된 콜 스택도 두 개 이상의 스레드를 사용할 때 실제 위반 코드 라인을 숨길 수 있습니다!

예:한 스레드는 루비 해시를 반복하고 다른 스레드는 수정하려고 합니다. 붐!예외!사용 중인 해시를 수정하려고 할 때 나타나는 스택 추적의 문제는 해시를 수정하려는 위치까지의 함수 체인을 보여주지만 현재 누가 (소유자인지) 병렬로 반복하는지는 보여주지 않는다는 것입니다!현재 실행 중인 모든 스레드에 대한 스택 추적을 인쇄하여 확인하는 방법은 다음과 같습니다.이 작업은 다음과 같습니다.

# 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

위의 코드 스니펫은 여러분이 실제로 얼마나 많은 스레드를 가지고 있는지 보여줄 수 있기 때문에 (엑스레이처럼) 교육적인 목적으로도 유용합니다. (몇 개가 있다고 생각했는지에 비해 - 종종 그 두 개는 다른 숫자입니다.;)

역추적 루비 보석(저는 저자입니다)도 사용할 수 있습니다.

require 'backtrace'
begin
  # do something dangerous
rescue StandardError => e
  puts Backtrace.new(e)
end

언급URL : https://stackoverflow.com/questions/376513/how-do-i-get-ruby-to-print-a-full-backtrace-instead-of-a-truncated-one