2012-06-20 36 views
108

Tôi muốn ghi nhật ký hiện tại (stacktrace) trong ứng dụng Rails 3 mà không có xảy ra ngoại lệ. Có ý tưởng nào không?Nhận dấu vết ngăn xếp hiện tại trong Ruby mà không cần nêu một ngoại lệ

Tại sao tôi muốn điều này? Tôi đang cố gắng theo dõi các cuộc gọi được thực hiện khi Rails tìm kiếm một mẫu để tôi có thể chọn một phần của quy trình để ghi đè (vì tôi muốn thay đổi đường dẫn xem cho một bộ điều khiển được phân lớp cụ thể của tôi).

Tôi muốn gọi nó từ tệp: gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb. Tôi biết đó không phải là thực hành tốt nhất, nhưng tôi biết nó là hạ lưu của ngăn xếp từ nơi tìm kiếm các mẫu xảy ra.

+4

giải pháp bẩn: nâng một ngoại lệ đó, giải cứu nó ngay lập tức và đăng nhập 'e.backtrace'. Tôi đã nhìn thấy nó trong một trong những dự án tôi đang làm việc với. Không phải là cách tiếp cận đẹp nhất, nhưng nó hoạt động. Hy vọng được nghe một giải pháp tốt hơn từ người khác, mặc dù. –

+0

Rực rỡ. Cảm ơn bạn. – JellicleCat

Trả lời

155

Bạn có thể sử dụng Kernel#caller:

# /tmp/caller.rb 

def foo 
    puts caller # Kernel#caller returns an array of strings 
end 

def bar 
    foo 
end 

def baz 
    bar 
end 

baz 

Output:

caller.rb:8:in `bar' 
caller.rb:12:in `baz' 
caller.rb:15:in `<main>' 
+0

Rất tiện dụng, rất đơn giản - cảm ơn! –

+0

Không phải là 'Kernel.caller' - có dấu chấm? 'Kernel.new.caller' không được định nghĩa ở đây – ecoologic

+7

Không, về mặt kỹ thuật' người gọi' là một phương thức thể hiện. Vì module 'Kernel' được bao gồm trong mọi lớp Ruby (ngoại trừ' BasicObject' trong 1.9), nó có sẵn như là phương thức instance trên bất kỳ đối tượng nào (mặc dù nó là private). Bạn không thể gọi nó là 'Kernel.new.caller' đơn giản chỉ vì bạn không thể khởi tạo một mô-đun (nó không có phương thức' mới'). –

3

tôi sử dụng để hiển thị một trang lỗi tùy chỉnh khi ngoại lệ được nâng lên.

rescue_from Exception do |exception| 
    logger.error exception.class 
    logger.error exception.message 
    logger.error exception.backtrace.join "\n" 
    @exception = exception 


    # ExceptionNotifier::Notifier.exception_notification env, @exception 

    respond_to do |format| 
    if [AbstractController::ActionNotFound, ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownAction].include?(exception.class) 
     format.html { render :template => "errors/404", :status => 404 } 
     format.js { render :nothing => true, :status => 404 } 
     format.xml { render :nothing => true, :status => 404 } 
    elsif exception.class == CanCan::AccessDenied 
     format.html { 
     render :template => "errors/401", :status => 401 #, :layout => 'application' 
     } 
     # format.js { render :json => { :errors => [exception.message] }, :status => 401 } 
     # format.js { render :js => 'alert("Hello 401")' } 
     format.js { render :template => 'errors/401.js.erb' } 

    else 
     ExceptionNotifier::Notifier.exception_notification(env, exception).deliver   
     format.html { render :template => "errors/500", :status => 500 } #, :layout => 'im2/application' } 
     # format.js { render :nothing => true, :status => 500 } 
     format.js { render :template => 'errors/500.js.erb' } 

    end 
    end 
end 
5

Hãy thử sử dụng

Thread.current.backtrace 
Các vấn đề liên quan