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,6 +71,9 @@ $(function() { | ||
71 | tab.closest('.tab-bar').find('a.active').removeClass('active'); | 71 | tab.closest('.tab-bar').find('a.active').removeClass('active'); |
72 | tab.addClass('active'); | 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 | $('.panel').hide(); | 77 | $('.panel').hide(); |
75 | panel.show(); | 78 | panel.show(); |
76 | } | 79 | } |
@@ -94,11 +97,17 @@ $(function() { | @@ -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 | $('td.backtrace_separator').hide(); | 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,27 +741,28 @@ table.backtrace td.line { | ||
741 | vertical-align: top; | 741 | vertical-align: top; |
742 | white-space: nowrap; | 742 | white-space: nowrap; |
743 | } | 743 | } |
744 | - | ||
745 | table.backtrace td.line .file { | 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 | table.backtrace td.line .method { | 747 | table.backtrace td.line .method { |
754 | color: #aaa; | 748 | color: #aaa; |
755 | - font-weight:bold; | 749 | + font-weight: bold; |
756 | } | 750 | } |
757 | 751 | ||
758 | table.backtrace td.line.in-app { | 752 | table.backtrace td.line.in-app { |
759 | color: #2adb2e; | 753 | color: #2adb2e; |
760 | background-color: #2f2f2f; | 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 | table.backtrace td.line.in-app .method { color: #2ACB2E; } | 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 | /* External backtrace classes and separators */ | 766 | /* External backtrace classes and separators */ |
766 | table.backtrace tr.hidden_external_backtrace { | 767 | table.backtrace tr.hidden_external_backtrace { |
767 | display: none; | 768 | display: none; |
app/helpers/notices_helper.rb
1 | # encoding: utf-8 | 1 | # encoding: utf-8 |
2 | module NoticesHelper | 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 | render :partial => "notices/atom_entry.html.haml", :locals => {:notice => notice} | 8 | render :partial => "notices/atom_entry.html.haml", :locals => {:notice => notice} |
5 | end | 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 | return link_to_github(app, line, text) if app.github_url? | 14 | return link_to_github(app, line, text) if app.github_url? |
10 | if app.issue_tracker && app.issue_tracker.respond_to?(:url_to_file) | 15 | if app.issue_tracker && app.issue_tracker.respond_to?(:url_to_file) |
11 | # Return link to file on tracker if issue tracker supports this | 16 | # Return link to file on tracker if issue tracker supports this |
@@ -36,7 +41,7 @@ module NoticesHelper | @@ -36,7 +41,7 @@ module NoticesHelper | ||
36 | def grouped_lines(lines) | 41 | def grouped_lines(lines) |
37 | line_groups = [] | 42 | line_groups = [] |
38 | lines.each do |line| | 43 | lines.each do |line| |
39 | - in_app = Notice.in_app_backtrace_line?(line) | 44 | + in_app = in_app_backtrace_line?(line) |
40 | if line_groups.last && line_groups.last[0] == in_app | 45 | if line_groups.last && line_groups.last[0] == in_app |
41 | line_groups.last[1] << line | 46 | line_groups.last[1] << line |
42 | else | 47 | else |
@@ -48,12 +53,16 @@ module NoticesHelper | @@ -48,12 +53,16 @@ module NoticesHelper | ||
48 | 53 | ||
49 | def path_for_backtrace_line(line) | 54 | def path_for_backtrace_line(line) |
50 | path = File.dirname(line['file']) | 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 | end | 62 | end |
53 | 63 | ||
54 | def file_for_backtrace_line(line) | 64 | def file_for_backtrace_line(line) |
55 | file = File.basename(line['file']) | 65 | file = File.basename(line['file']) |
56 | - line['number'].present? ? "#{file}:#{line['number']}" : file | ||
57 | end | 66 | end |
58 | end | 67 | end |
59 | 68 |
app/models/notice.rb
@@ -62,10 +62,6 @@ class Notice | @@ -62,10 +62,6 @@ class Notice | ||
62 | where | 62 | where |
63 | end | 63 | end |
64 | 64 | ||
65 | - def self.in_app_backtrace_line?(line) | ||
66 | - !!(line['file'] =~ %r{^\[PROJECT_ROOT\]/(?!(vendor))}) | ||
67 | - end | ||
68 | - | ||
69 | def request | 65 | def request |
70 | read_attribute(:request) || {} | 66 | read_attribute(:request) || {} |
71 | end | 67 | end |
app/views/notices/_backtrace.html.haml
@@ -2,11 +2,11 @@ | @@ -2,11 +2,11 @@ | ||
2 | %table.backtrace | 2 | %table.backtrace |
3 | -# Group lines into internal / external so we can toggle the external backtrace | 3 | -# Group lines into internal / external so we can toggle the external backtrace |
4 | -# Includes a margin of x lines that are not toggled. | 4 | -# Includes a margin of x lines that are not toggled. |
5 | - - em = 3 # (external backtrace margin) | 5 | + - em = 4 # (external backtrace margin) |
6 | - grouped_lines(lines).each do |in_app, line_group| | 6 | - grouped_lines(lines).each do |in_app, line_group| |
7 | - if !in_app && line_group.size > (em * 3) | 7 | - if !in_app && line_group.size > (em * 3) |
8 | = render :partial => 'notices/backtrace_line', :collection => line_group[0, em], :as => :line | 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 | %tr | 10 | %tr |
11 | %td.line.backtrace_separator | 11 | %td.line.backtrace_separator |
12 | %span ... | 12 | %span ... |
app/views/notices/_backtrace_line.html.haml
1 | %tr{:class => defined?(row_class) ? row_class : nil} | 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 | %span.method= line['method'] | 9 | %span.method= line['method'] |
spec/models/notice_spec.rb
@@ -24,36 +24,6 @@ describe Notice do | @@ -24,36 +24,6 @@ describe Notice do | ||
24 | end | 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 | describe "key sanitization" do | 27 | describe "key sanitization" do |
58 | before do | 28 | before do |
59 | @hash = { "some.key" => { "$nested.key" => {"$Path" => "/", "some$key" => "key"}}} | 29 | @hash = { "some.key" => { "$nested.key" => {"$Path" => "/", "some$key" => "key"}}} |