Commit 93030e53f8f6b6f0ff0975e75ea84fa75f337591
1 parent
4239e83e
Exists in
master
and in
1 other branch
Errs#show with backtrace
Showing
9 changed files
with
121 additions
and
3 deletions
Show diff stats
Gemfile
@@ -5,6 +5,7 @@ gem 'libxml-ruby' | @@ -5,6 +5,7 @@ gem 'libxml-ruby' | ||
5 | gem 'bson_ext', :require => nil | 5 | gem 'bson_ext', :require => nil |
6 | gem 'mongoid', '2.0.0.beta.15' | 6 | gem 'mongoid', '2.0.0.beta.15' |
7 | gem 'haml' | 7 | gem 'haml' |
8 | +gem 'will_paginate' | ||
8 | 9 | ||
9 | group :development, :test do | 10 | group :development, :test do |
10 | gem 'rspec-rails', '>= 2.0.0.beta.19' | 11 | gem 'rspec-rails', '>= 2.0.0.beta.19' |
Gemfile.lock
app/controllers/errs_controller.rb
@@ -4,4 +4,11 @@ class ErrsController < ApplicationController | @@ -4,4 +4,11 @@ class ErrsController < ApplicationController | ||
4 | @errs = Err.unresolved.paginate(:page => params[:page]) | 4 | @errs = Err.unresolved.paginate(:page => params[:page]) |
5 | end | 5 | end |
6 | 6 | ||
7 | + def show | ||
8 | + @project = Project.find(params[:project_id]) | ||
9 | + @err = @project.errs.find(params[:id]) | ||
10 | + @notices = @err.notices.paginate(:page => (params[:notice] || @err.notices.count), :per_page => 1) | ||
11 | + @notice = @notices.first | ||
12 | + end | ||
13 | + | ||
7 | end | 14 | end |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +- content_for :title, @err.message | ||
2 | +- content_for :meta do | ||
3 | + %strong Where: | ||
4 | + = @err.where | ||
5 | + %strong Environment: | ||
6 | + = @err.environment.titleize | ||
7 | + %strong Type: | ||
8 | + = @err.klass | ||
9 | + %strong Last Notice: | ||
10 | + = @err.last_notice_at.to_s(:micro) | ||
11 | +- content_for :action_bar do | ||
12 | + = will_paginate @notices, :param_name => :notice, :page_links => false | ||
13 | + .float-left viewing occurrence #{@notices.current_page} of #{@notices.total_pages} | ||
14 | + = link_to "back to '#{@project.name}'", project_path(@project) | ||
15 | + | | ||
16 | + = link_to 'resolve', '#' if @err.unresolved? | ||
17 | + | ||
18 | +%h3#backtrace Backtrace | ||
19 | += render 'notices/backtrace', :lines => @notice.backtrace | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
app/views/layouts/application.html.haml
@@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
18 | #content-title | 18 | #content-title |
19 | %h1= yield :title | 19 | %h1= yield :title |
20 | %span.meta= yield :meta | 20 | %span.meta= yield :meta |
21 | - - if action_bar = yield(:action_bar) | 21 | + - if (action_bar = yield(:action_bar)).present? |
22 | #action-bar | 22 | #action-bar |
23 | = action_bar | 23 | = action_bar |
24 | #content | 24 | #content |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +.backtrace | ||
2 | + %table | ||
3 | + %tr | ||
4 | + %th | ||
5 | + %ul.line-numbers | ||
6 | + - lines.each do |line| | ||
7 | + %li= line['number'] | ||
8 | + %td | ||
9 | + %ul.lines | ||
10 | + - lines.each do |line| | ||
11 | + %li{:class => (line['file'].gsub!('[PROJECT_ROOT]','') ? 'in-project' : nil)} | ||
12 | + = line['file'] | ||
13 | + → | ||
14 | + %strong= line['method'] | ||
0 | \ No newline at end of file | 15 | \ No newline at end of file |
app/views/shared/_navigation.html.haml
@@ -2,5 +2,5 @@ | @@ -2,5 +2,5 @@ | ||
2 | %ul | 2 | %ul |
3 | //%li= link_to 'Dashboard', admin_dashboard_path, :class => active_if_here(:dashboards) | 3 | //%li= link_to 'Dashboard', admin_dashboard_path, :class => active_if_here(:dashboards) |
4 | %li= link_to 'Projects', projects_path, :class => active_if_here(:projects) | 4 | %li= link_to 'Projects', projects_path, :class => active_if_here(:projects) |
5 | - %li= link_to 'Errors', errs_path, :class => active_if_here(:errs => :index) | 5 | + %li= link_to 'Errors', errs_path, :class => active_if_here(:errs) |
6 | %div.clear | 6 | %div.clear |
7 | \ No newline at end of file | 7 | \ No newline at end of file |
public/stylesheets/application.css
@@ -9,6 +9,8 @@ body { | @@ -9,6 +9,8 @@ body { | ||
9 | } | 9 | } |
10 | 10 | ||
11 | /* Convenience Classes */ | 11 | /* Convenience Classes */ |
12 | +.float-left { float: left; } | ||
13 | +.float-right { float: right; } | ||
12 | .clear { clear: both; } | 14 | .clear { clear: both; } |
13 | .clear-left { clear: left; } | 15 | .clear-left { clear: left; } |
14 | .clear-right { clear: right; } | 16 | .clear-right { clear: right; } |
@@ -171,6 +173,26 @@ pre { | @@ -171,6 +173,26 @@ pre { | ||
171 | .html ul li { margin-bottom: 0.5em; list-style: disc; } | 173 | .html ul li { margin-bottom: 0.5em; list-style: disc; } |
172 | .html ol li { margin-bottom: 0.5em; list-style: decimal; } | 174 | .html ol li { margin-bottom: 0.5em; list-style: decimal; } |
173 | 175 | ||
176 | +/* Pagination */ | ||
177 | +.pagination { | ||
178 | + float: left; | ||
179 | + margin-right: 0.8em; | ||
180 | + text-align: left; | ||
181 | + font-size: 0.9em; | ||
182 | +} | ||
183 | +.pagination a, .pagination span { | ||
184 | + display: inline-block; | ||
185 | + padding: 0 0.3em; | ||
186 | + background-color: #666666; | ||
187 | + border: 1px solid #505050; | ||
188 | +} | ||
189 | +.pagination a:hover { | ||
190 | + text-decoration: none !important; | ||
191 | +} | ||
192 | +.pagination span { | ||
193 | + color: #AAA; | ||
194 | +} | ||
195 | + | ||
174 | /* Projects Table */ | 196 | /* Projects Table */ |
175 | table.projects td.name, table.errs td.message { | 197 | table.projects td.name, table.errs td.message { |
176 | width: 100%; | 198 | width: 100%; |
@@ -189,4 +211,33 @@ table.errs td.message a { | @@ -189,4 +211,33 @@ table.errs td.message a { | ||
189 | table.errs td.message em { | 211 | table.errs td.message em { |
190 | color: #727272; | 212 | color: #727272; |
191 | font-size: 0.9em; | 213 | font-size: 0.9em; |
214 | +} | ||
215 | + | ||
216 | +/* Backtrace */ | ||
217 | +.backtrace { | ||
218 | + width: 100%; | ||
219 | + overflow: auto; | ||
220 | +} | ||
221 | +.backtrace table { | ||
222 | + margin: 0; | ||
223 | +} | ||
224 | +.backtrace td { | ||
225 | + width: 100%; | ||
226 | + padding: 0; | ||
227 | + margin: 0; | ||
228 | + color: #A2A2A2; | ||
229 | + background-color: #222 !important; | ||
230 | +} | ||
231 | +.backtrace ul.line-numbers li { | ||
232 | + text-align: right; | ||
233 | +} | ||
234 | +.backtrace ul.lines { | ||
235 | + padding: 10px 8px; | ||
236 | + overflow: auto; | ||
237 | +} | ||
238 | +.backtrace li { | ||
239 | + white-space: nowrap; | ||
240 | +} | ||
241 | +.backtrace li.in-project { | ||
242 | + color: #2adb2e; | ||
192 | } | 243 | } |
193 | \ No newline at end of file | 244 | \ No newline at end of file |
spec/controllers/errs_controller_spec.rb
@@ -3,15 +3,40 @@ require 'spec_helper' | @@ -3,15 +3,40 @@ require 'spec_helper' | ||
3 | describe ErrsController do | 3 | describe ErrsController do |
4 | 4 | ||
5 | let(:project) { Factory(:project) } | 5 | let(:project) { Factory(:project) } |
6 | + let(:err) { Factory(:err, :project => project) } | ||
6 | 7 | ||
7 | describe "GET /errs" do | 8 | describe "GET /errs" do |
8 | it "gets a paginated list of unresolved errors" do | 9 | it "gets a paginated list of unresolved errors" do |
9 | errors = WillPaginate::Collection.new(1,30) | 10 | errors = WillPaginate::Collection.new(1,30) |
10 | - 3.times { errors << Factory(:err, :project => project) } | 11 | + 3.times { errors << Factory(:err) } |
11 | Err.should_receive(:unresolved).and_return(mock('proxy', :paginate => errors)) | 12 | Err.should_receive(:unresolved).and_return(mock('proxy', :paginate => errors)) |
12 | get :index | 13 | get :index |
13 | assigns(:errs).should == errors | 14 | assigns(:errs).should == errors |
14 | end | 15 | end |
15 | end | 16 | end |
16 | 17 | ||
18 | + describe "GET /errs/:id" do | ||
19 | + before do | ||
20 | + 3.times { Factory(:notice, :err => err)} | ||
21 | + end | ||
22 | + | ||
23 | + it "finds the project" do | ||
24 | + get :show, :project_id => project.id, :id => err.id | ||
25 | + assigns(:project).should == project | ||
26 | + end | ||
27 | + | ||
28 | + it "finds the err" do | ||
29 | + get :show, :project_id => project.id, :id => err.id | ||
30 | + assigns(:err).should == err | ||
31 | + end | ||
32 | + | ||
33 | + it "paginates the notices, 1 at a time" do | ||
34 | + Project.stub(:find).with(project.id).and_return(project) | ||
35 | + project.errs.stub(:find).with(err.id).and_return(err) | ||
36 | + err.notices.should_receive(:paginate).with(:page => 3, :per_page => 1). | ||
37 | + and_return(WillPaginate::Collection.new(1,1) << err.notices.first) | ||
38 | + get :show, :project_id => project.id, :id => err.id | ||
39 | + end | ||
40 | + end | ||
41 | + | ||
17 | end | 42 | end |