Commit 26f14111f08cd56e6ef436e0b61353abd6f72446
1 parent
6035cb2c
Exists in
master
and in
1 other branch
Improved backtrace formatting.
Make whole (path/file) into github link, hide [PROJECT_ROOT], and replace [GEM_ROOT]/gems/****-*.*.* with bold gem name. Improved CSS colors.
Showing
7 changed files
with
48 additions
and
60 deletions
Show diff stats
app/assets/javascripts/errbit.js
| ... | ... | @@ -71,6 +71,9 @@ $(function() { |
| 71 | 71 | tab.closest('.tab-bar').find('a.active').removeClass('active'); |
| 72 | 72 | tab.addClass('active'); |
| 73 | 73 | |
| 74 | + // If clicking into 'backtrace' tab, hide external backtrace | |
| 75 | + if (tab.attr('rel') == "backtrace") { hide_external_backtrace(); } | |
| 76 | + | |
| 74 | 77 | $('.panel').hide(); |
| 75 | 78 | panel.show(); |
| 76 | 79 | } |
| ... | ... | @@ -94,11 +97,17 @@ $(function() { |
| 94 | 97 | }); |
| 95 | 98 | } |
| 96 | 99 | |
| 97 | - init(); | |
| 98 | - | |
| 99 | - // Show external backtrace lines when clicking separator | |
| 100 | - $('td.backtrace_separator span').live('click', function(){ | |
| 101 | - $('tr.hidden_external_backtrace').removeClass('hidden_external_backtrace'); | |
| 100 | + function hide_external_backtrace() { | |
| 101 | + $('tr.toggle_external_backtrace').hide(); | |
| 102 | + $('td.backtrace_separator').show(); | |
| 103 | + } | |
| 104 | + function show_external_backtrace() { | |
| 105 | + $('tr.toggle_external_backtrace').show(); | |
| 102 | 106 | $('td.backtrace_separator').hide(); |
| 103 | - }); | |
| 107 | + } | |
| 108 | + // Show external backtrace lines when clicking separator | |
| 109 | + $('td.backtrace_separator span').live('click', show_external_backtrace); | |
| 110 | + // Hide external backtrace on page load | |
| 111 | + hide_external_backtrace(); | |
| 112 | + init(); | |
| 104 | 113 | }); | ... | ... |
app/assets/stylesheets/errbit.css
| ... | ... | @@ -741,27 +741,28 @@ table.backtrace td.line { |
| 741 | 741 | vertical-align: top; |
| 742 | 742 | white-space: nowrap; |
| 743 | 743 | } |
| 744 | - | |
| 745 | 744 | table.backtrace td.line .file { |
| 746 | - color: #ededed; | |
| 747 | - font-weight:bold; | |
| 748 | -} | |
| 749 | -table.backtrace td.line .file a { | |
| 750 | - color: #21A4FF; | |
| 745 | + font-weight: bold; | |
| 751 | 746 | } |
| 752 | - | |
| 753 | 747 | table.backtrace td.line .method { |
| 754 | 748 | color: #aaa; |
| 755 | - font-weight:bold; | |
| 749 | + font-weight: bold; | |
| 756 | 750 | } |
| 757 | 751 | |
| 758 | 752 | table.backtrace td.line.in-app { |
| 759 | 753 | color: #2adb2e; |
| 760 | 754 | background-color: #2f2f2f; |
| 761 | 755 | } |
| 762 | -table.backtrace td.line.in-app .file { color: #2AEB2E; } | |
| 756 | +table.backtrace td.line.in-app .path, | |
| 757 | +table.backtrace td.line.in-app .number { color: #2ACB2E; } | |
| 758 | +table.backtrace td.line.in-app .file { color: #3AFB3E; } | |
| 763 | 759 | table.backtrace td.line.in-app .method { color: #2ACB2E; } |
| 764 | 760 | |
| 761 | +table.backtrace td.line.in-app a .path, | |
| 762 | +table.backtrace td.line.in-app a .number, | |
| 763 | +table.backtrace td.line.in-app a:hover { color: #21B4FF; } | |
| 764 | +table.backtrace td.line.in-app a .file { color: #31C4FF; } | |
| 765 | + | |
| 765 | 766 | /* External backtrace classes and separators */ |
| 766 | 767 | table.backtrace tr.hidden_external_backtrace { |
| 767 | 768 | display: none; | ... | ... |
app/helpers/notices_helper.rb
| 1 | 1 | # encoding: utf-8 |
| 2 | 2 | module NoticesHelper |
| 3 | - def notice_atom_summary notice | |
| 3 | + def in_app_backtrace_line?(line) | |
| 4 | + !!(line['file'] =~ %r{^\[PROJECT_ROOT\]/(?!(vendor))}) | |
| 5 | + end | |
| 6 | + | |
| 7 | + def notice_atom_summary(notice) | |
| 4 | 8 | render :partial => "notices/atom_entry.html.haml", :locals => {:notice => notice} |
| 5 | 9 | end |
| 6 | 10 | |
| 7 | - def link_to_source_file(app, line, text) | |
| 8 | - if Notice.in_app_backtrace_line?(line) | |
| 11 | + def link_to_source_file(app, line, &block) | |
| 12 | + text = capture_haml(&block) | |
| 13 | + if in_app_backtrace_line?(line) | |
| 9 | 14 | return link_to_github(app, line, text) if app.github_url? |
| 10 | 15 | if app.issue_tracker && app.issue_tracker.respond_to?(:url_to_file) |
| 11 | 16 | # Return link to file on tracker if issue tracker supports this |
| ... | ... | @@ -36,7 +41,7 @@ module NoticesHelper |
| 36 | 41 | def grouped_lines(lines) |
| 37 | 42 | line_groups = [] |
| 38 | 43 | lines.each do |line| |
| 39 | - in_app = Notice.in_app_backtrace_line?(line) | |
| 44 | + in_app = in_app_backtrace_line?(line) | |
| 40 | 45 | if line_groups.last && line_groups.last[0] == in_app |
| 41 | 46 | line_groups.last[1] << line |
| 42 | 47 | else |
| ... | ... | @@ -48,12 +53,16 @@ module NoticesHelper |
| 48 | 53 | |
| 49 | 54 | def path_for_backtrace_line(line) |
| 50 | 55 | path = File.dirname(line['file']) |
| 51 | - path == "." ? "" : path + '/' | |
| 56 | + return '' if path == '.' | |
| 57 | + # Remove [PROJECT_ROOT] | |
| 58 | + path.gsub!('[PROJECT_ROOT]/', '') | |
| 59 | + # Make gem name bold if starts with [GEM_ROOT]/gems | |
| 60 | + path.gsub!(/\[GEM_ROOT\]\/gems\/([^\/]+)/, "<strong>\\1</strong>") | |
| 61 | + (path << '/').html_safe | |
| 52 | 62 | end |
| 53 | 63 | |
| 54 | 64 | def file_for_backtrace_line(line) |
| 55 | 65 | file = File.basename(line['file']) |
| 56 | - line['number'].present? ? "#{file}:#{line['number']}" : file | |
| 57 | 66 | end |
| 58 | 67 | end |
| 59 | 68 | ... | ... |
app/models/notice.rb
app/views/notices/_backtrace.html.haml
| ... | ... | @@ -2,11 +2,11 @@ |
| 2 | 2 | %table.backtrace |
| 3 | 3 | -# Group lines into internal / external so we can toggle the external backtrace |
| 4 | 4 | -# Includes a margin of x lines that are not toggled. |
| 5 | - - em = 3 # (external backtrace margin) | |
| 5 | + - em = 4 # (external backtrace margin) | |
| 6 | 6 | - grouped_lines(lines).each do |in_app, line_group| |
| 7 | 7 | - if !in_app && line_group.size > (em * 3) |
| 8 | 8 | = render :partial => 'notices/backtrace_line', :collection => line_group[0, em], :as => :line |
| 9 | - = render :partial => 'notices/backtrace_line', :collection => line_group[em, line_group.size - (em * 2)], :as => :line, :locals => {:row_class => 'hidden_external_backtrace'} | |
| 9 | + = render :partial => 'notices/backtrace_line', :collection => line_group[em, line_group.size - (em * 2)], :as => :line, :locals => {:row_class => 'toggle_external_backtrace'} | |
| 10 | 10 | %tr |
| 11 | 11 | %td.line.backtrace_separator |
| 12 | 12 | %span ... | ... | ... |
app/views/notices/_backtrace_line.html.haml
| 1 | 1 | %tr{:class => defined?(row_class) ? row_class : nil} |
| 2 | - %td.line{:class => (Notice.in_app_backtrace_line?(line) ? 'in-app' : nil)} | |
| 3 | - %span.path>= path_for_backtrace_line(line) | |
| 4 | - %span.file= link_to_source_file(@app, line, file_for_backtrace_line(line)).html_safe | |
| 2 | + %td.line{:class => (in_app_backtrace_line?(line) ? 'in-app' : nil)} | |
| 3 | + = link_to_source_file(@app, line) do | |
| 4 | + %span.path>= path_for_backtrace_line(line) | |
| 5 | + %span.file>= file_for_backtrace_line(line) | |
| 6 | + - if line['number'].present? | |
| 7 | + %span.number>= ":#{line['number']}" | |
| 5 | 8 | → |
| 6 | 9 | %span.method= line['method'] | ... | ... |
spec/models/notice_spec.rb
| ... | ... | @@ -24,36 +24,6 @@ describe Notice do |
| 24 | 24 | end |
| 25 | 25 | |
| 26 | 26 | |
| 27 | - context '.in_app_backtrace_line?' do | |
| 28 | - let(:backtrace) do [{ | |
| 29 | - 'number' => rand(999), | |
| 30 | - 'file' => '[GEM_ROOT]/gems/actionpack-3.0.4/lib/action_controller/metal/rescue.rb', | |
| 31 | - 'method' => ActiveSupport.methods.shuffle.first | |
| 32 | - }, { | |
| 33 | - 'number' => rand(999), | |
| 34 | - 'file' => '[PROJECT_ROOT]/vendor/plugins/seamless_database_pool/lib/seamless_database_pool/controller_filter.rb', | |
| 35 | - 'method' => ActiveSupport.methods.shuffle.first | |
| 36 | - }, { | |
| 37 | - 'number' => rand(999), | |
| 38 | - 'file' => '[PROJECT_ROOT]/lib/set_headers.rb', | |
| 39 | - 'method' => ActiveSupport.methods.shuffle.first | |
| 40 | - }] | |
| 41 | - end | |
| 42 | - | |
| 43 | - it "should be false for line not starting with PROJECT_ROOT" do | |
| 44 | - Notice.in_app_backtrace_line?(backtrace[0]).should == false | |
| 45 | - end | |
| 46 | - | |
| 47 | - it "should be false for file in vendor dir" do | |
| 48 | - Notice.in_app_backtrace_line?(backtrace[1]).should == false | |
| 49 | - end | |
| 50 | - | |
| 51 | - it "should be true for application file" do | |
| 52 | - Notice.in_app_backtrace_line?(backtrace[2]).should == true | |
| 53 | - end | |
| 54 | - end | |
| 55 | - | |
| 56 | - | |
| 57 | 27 | describe "key sanitization" do |
| 58 | 28 | before do |
| 59 | 29 | @hash = { "some.key" => { "$nested.key" => {"$Path" => "/", "some$key" => "key"}}} | ... | ... |