Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Thành Thạo Ruby Stack Traces: Cách Đọc & Chẩn Đoán Lỗi

Khi lỗi xảy ra trong ứng dụng, Ruby raise exception và in stack trace ra log. Bài này xem cách đọc stack trace và dùng nó định vị source của exception trong ứng dụng.

Call Stack

Khi gọi method, Ruby đặt stack frame lên call stack (hay "runtime stack", thường gọi "stack"). Stack frame là memory allocation giữ method arguments, space cho internal variables, và return address của caller.

# divide.rb def divide(a, b) "Dividing #{a} by #{b} gives #{a / b}." end puts divide(8, 4)

Khi một method (divide) gọi method khác (Fixnum#/, hoặc / ngắn gọn), cái sau đặt lên đỉnh stack, vì cần execute trước cái đầu mới finish. Khi gọi divide(8, 4) ví dụ này, Ruby execute actions theo thứ tự:

  1. Call 8./(4)
  2. Collect division result (2), đặt vào string
  3. Collect string ("Dividing 8 by 4 gives 2"), in ra console với puts

Stack Traces

Stack trace (thường gọi "backtrace" trong Ruby, cũng gọi "stack backtrace" và "stack traceback") là human-readable representation của stack tại moment cụ thể chạy chương trình. Stack trace cho call / method trông như sau, show nó được gọi trong method divide line 2, được gọi trong method <main> line 5.

divide.rb:2:in `/' divide.rb:2:in `divide' divide.rb:5:in `<main>' 

Trong ví dụ trên, gọi divide method với 0 làm argument dẫn đến ZeroDivisionError exception.

# divide_by_zero.rb def divide(a, b) "Dividing #{a} by #{b} gives #{a / b}." end puts divide(8, 0)

Khi đó, Ruby in exception, kèm stack trace, ra console. Stack trace show stack dạng human-readable, với location mỗi method trong code, giúp pinpoint exception từ đâu.

$ ruby divide_by_zero.rb divide_by_zero.rb:2:in `/': divided by 0 (ZeroDivisionError) from divide_by_zero.rb:2:in `divide' from divide_by_zero.rb:5:in `<main>' 
  1. Dòng đầu stack trace, thấy ZeroDivisionError raise với "divided by 0" message. Bên cạnh exception, thấy xảy ra ở divide_by_zero.rb:2:in `/', nghĩa là error raise từ line 2 file ví dụ, từ method tên / (là Fixnum#/, vì first argument là Fixnum 8).

  2. Dòng 2 stack trace show / method được gọi từ đâu. Trường hợp này, từ method divide line 2.

  3. Dòng cuối show divide được gọi từ <main>,指初始上下文Ruby应用程序。通常意味着它是在任何“真实”方法之外被调用的。

LƯU Ý: Ruby 2.5, logger in stack trace ngược để fit terminal window. Dòng cuối show exception, trước đó line exception xảy ra. Các dòng trên là route lên stack.

Hiểu Stack Traces

Stack trace cho dump trạng thái call stack hiện tại khi exception raise, giúp tìm ra chỗ sai.

Mặc dù dòng đầu stacktrace show line exception xảy ra, không luôn show source của error. Ví dụ trên, chương序 execute proper, nhưng không handle data pass cho divide method. Đi lên stack trace dẫn đến nơi nó được gọi, là source của problem.

Chúng tôi rất muốn biết bạn thấy bài này như thế nào, nếu có câu hỏi, và bạn muốn đọc gì tiếp theo, hãy cho biết @AppSignal.