Skip to content

Commit 0c7c62c

Browse files
Decouple variable_info from ErrorPage instance
1 parent 834a877 commit 0c7c62c

File tree

5 files changed

+46
-31
lines changed

5 files changed

+46
-31
lines changed

lib/better_errors/error_page.rb

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
module BetterErrors
66
# @private
77
class ErrorPage
8+
VariableInfo = Struct.new(:frame, :editor_url, :rails_params, :rack_session, :start_time)
9+
810
def self.template_path(template_name)
911
File.expand_path("../templates/#{template_name}.erb", __FILE__)
1012
end
@@ -13,6 +15,15 @@ def self.template(template_name)
1315
Erubi::Engine.new(File.read(template_path(template_name)), escape: true)
1416
end
1517

18+
def self.render_template(template_name, locals)
19+
locals.send(:eval, self.template(template_name).src)
20+
rescue => e
21+
# Fix the backtrace, which doesn't identify the template that failed (within Better Errors).
22+
# We don't know the line number, so just injecting the template path has to be enough.
23+
e.backtrace.unshift "#{self.template_path(template_name)}:0"
24+
raise
25+
end
26+
1627
attr_reader :exception, :env, :repls
1728

1829
def initialize(exception, env)
@@ -26,20 +37,21 @@ def id
2637
@id ||= SecureRandom.hex(8)
2738
end
2839

29-
def render(template_name = "main", csrf_token = nil, csp_nonce = nil)
30-
binding.eval(self.class.template(template_name).src)
31-
rescue => e
32-
# Fix the backtrace, which doesn't identify the template that failed (within Better Errors).
33-
# We don't know the line number, so just injecting the template path has to be enough.
34-
e.backtrace.unshift "#{self.class.template_path(template_name)}:0"
35-
raise
40+
def render_main(csrf_token, csp_nonce)
41+
frame = backtrace_frames[0]
42+
first_frame_variable_info = VariableInfo.new(frame, editor_url(frame), rails_params, rack_session, Time.now.to_f)
43+
self.class.render_template('main', binding)
44+
end
45+
46+
def render_text
47+
self.class.render_template('text', binding)
3648
end
3749

3850
def do_variables(opts)
3951
index = opts["index"].to_i
40-
@frame = backtrace_frames[index]
41-
@var_start_time = Time.now.to_f
42-
{ html: render("variable_info") }
52+
frame = backtrace_frames[index]
53+
variable_info = VariableInfo.new(frame, editor_url(frame), rails_params, rack_session, Time.now.to_f)
54+
{ html: self.class.render_template("variable_info", variable_info) }
4355
end
4456

4557
def do_eval(opts)
@@ -113,19 +125,19 @@ def request_path
113125
env["PATH_INFO"]
114126
end
115127

116-
def html_formatted_code_block(frame)
128+
def self.html_formatted_code_block(frame)
117129
CodeFormatter::HTML.new(frame.filename, frame.line).output
118130
end
119131

120-
def text_formatted_code_block(frame)
132+
def self.text_formatted_code_block(frame)
121133
CodeFormatter::Text.new(frame.filename, frame.line).output
122134
end
123135

124136
def text_heading(char, str)
125137
str + "\n" + char*str.size
126138
end
127139

128-
def inspect_value(obj)
140+
def self.inspect_value(obj)
129141
if BetterErrors.ignored_classes.include? obj.class.name
130142
"<span class='unsupported'>(Instance of ignored class. "\
131143
"#{obj.class.name ? "Remove #{CGI.escapeHTML(obj.class.name)} from" : "Modify"}"\

lib/better_errors/middleware.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ def show_error_page(env, exception=nil)
9898

9999
type, content = if @error_page
100100
if text?(env)
101-
[ 'plain', @error_page.render('text') ]
101+
[ 'plain', @error_page.render_text ]
102102
else
103-
[ 'html', @error_page.render('main', csrf_token, csp_nonce) ]
103+
[ 'html', @error_page.render_main(csrf_token, csp_nonce) ]
104104
end
105105
else
106106
[ 'html', no_errors_page ]

lib/better_errors/templates/text.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<%== text_heading("-", "%s, line %i" % [first_frame.pretty_path, first_frame.line]) %>
1010

1111
``` ruby
12-
<%== text_formatted_code_block(first_frame) %>```
12+
<%== ErrorPage.text_formatted_code_block(first_frame) %>```
1313

1414
App backtrace
1515
-------------
Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
<header class="trace_info clearfix">
22
<div class="title">
3-
<h2 class="name"><%= @frame.name %></h2>
3+
<h2 class="name"><%= frame.name %></h2>
44
<div class="location">
55
<span class="filename">
66
<a
7-
href="<%= editor_url(@frame) %>"
7+
href="<%= editor_url %>"
88
<%= ENV.key?('BETTER_ERRORS_INSIDE_FRAME') ? "target=_blank" : '' %>
9-
><%= @frame.pretty_path %></a>
9+
><%= frame.pretty_path %></a>
1010
</span>
1111
</div>
1212
</div>
1313
<div class="code_block clearfix">
14-
<%== html_formatted_code_block @frame %>
14+
<%== ErrorPage.html_formatted_code_block frame %>
1515
</div>
1616

17-
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
17+
<% if BetterErrors.binding_of_caller_available? && frame.frame_binding %>
1818
<div class="be-repl">
1919
<div class="be-console">
2020
<pre></pre>
@@ -24,7 +24,7 @@
2424
<% end %>
2525
</header>
2626

27-
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
27+
<% if BetterErrors.binding_of_caller_available? && frame.frame_binding %>
2828
<div class="hint live-console-hint">
2929
This is a live shell. Type in here.
3030
</div>
@@ -38,27 +38,28 @@
3838
</div>
3939
<% end %>
4040

41+
<%# TODO: move this outside of the frame info. It's not part of the frame. %>
4142
<div class="sub">
4243
<h3>Request info</h3>
4344
<div class='inset variables'>
4445
<table class="var_table">
4546
<% if rails_params %>
46-
<tr><td class="name">Request parameters</td><td><pre><%== inspect_value rails_params %></pre></td></tr>
47+
<tr><td class="name">Request parameters</td><td><pre><%== ErrorPage.inspect_value rails_params %></pre></td></tr>
4748
<% end %>
4849
<% if rack_session %>
49-
<tr><td class="name">Rack session</td><td><pre><%== inspect_value rack_session %></pre></td></tr>
50+
<tr><td class="name">Rack session</td><td><pre><%== ErrorPage.inspect_value rack_session %></pre></td></tr>
5051
<% end %>
5152
</table>
5253
</div>
5354
</div>
5455

55-
<% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
56+
<% if BetterErrors.binding_of_caller_available? && frame.frame_binding %>
5657
<div class="sub">
5758
<h3>Local Variables</h3>
5859
<div class='inset variables'>
5960
<table class="var_table">
60-
<% @frame.local_variables.each do |name, value| %>
61-
<tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
61+
<% frame.local_variables.each do |name, value| %>
62+
<tr><td class="name"><%= name %></td><td><pre><%== ErrorPage.inspect_value value %></pre></td></tr>
6263
<% end %>
6364
</table>
6465
</div>
@@ -68,12 +69,14 @@
6869
<h3>Instance Variables</h3>
6970
<div class="inset variables">
7071
<table class="var_table">
71-
<% @frame.instance_variables.each do |name, value| %>
72-
<tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
72+
<% frame.instance_variables.each do |name, value| %>
73+
<tr><td class="name"><%= name %></td><td><pre><%== ErrorPage.inspect_value value %></pre></td></tr>
7374
<% end %>
7475
</table>
7576
</div>
7677
</div>
78+
<% end %>
7779

78-
<!-- <%= Time.now.to_f - @var_start_time %> seconds -->
80+
<% if start_time %>
81+
<!-- variable_info took <%= Time.now.to_f - start_time %> seconds -->
7982
<% end %>

spec/better_errors/error_page_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module BetterErrors
1313

1414
let(:error_page) { ErrorPage.new exception, { "PATH_INFO" => "/some/path" } }
1515

16-
let(:response) { error_page.render }
16+
let(:response) { error_page.render_main("CSRF_TOKEN", "CSP_NONCE") }
1717

1818
let(:exception_binding) {
1919
local_a = :value_for_local_a

0 commit comments

Comments
 (0)