Skip to content

Commit

Permalink
Merge pull request #465 from connorshea/actionable-errors
Browse files Browse the repository at this point in the history
Support for Rails ActionableError
  • Loading branch information
RobinDaugherty committed May 14, 2020
2 parents 355966b + 87cc62d commit 448c9f2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
19 changes: 18 additions & 1 deletion lib/better_errors/error_page.rb
Expand Up @@ -28,6 +28,11 @@ def id

def render(template_name = "main")
binding.eval(self.class.template(template_name).src)
rescue => e
# Fix the backtrace, which doesn't identify the template that failed (within Better Errors).
# We don't know the line number, so just injecting the template path has to be enough.
e.backtrace.unshift "#{self.class.template_path(template_name)}:0"
raise
end

def do_variables(opts)
Expand Down Expand Up @@ -59,7 +64,19 @@ def exception_type
end

def exception_message
exception.message.lstrip
exception.message.strip.gsub(/(\r?\n\s*\r?\n)+/, "\n")
end

def active_support_actions
return [] unless defined?(ActiveSupport::ActionableError)

ActiveSupport::ActionableError.actions(exception.type)
end

def action_dispatch_action_endpoint
return unless defined?(ActionDispatch::ActionableExceptions)

ActionDispatch::ActionableExceptions.endpoint
end

def application_frames
Expand Down
24 changes: 22 additions & 2 deletions lib/better_errors/templates/main.erb
Expand Up @@ -146,14 +146,22 @@
}

/* Heading */
header.exception .fix-actions {
margin-top: .5em;
}

header.exception .fix-actions input[type=submit] {
font-weight: bold;
}

header.exception h2 {
font-weight: 200;
font-size: 11pt;
}

header.exception h2,
header.exception p {
line-height: 1.4em;
line-height: 1.5em;
overflow: hidden;
white-space: pre;
text-overflow: ellipsis;
Expand All @@ -166,7 +174,7 @@

header.exception p {
font-weight: 200;
font-size: 20pt;
font-size: 17pt;
color: white;
}

Expand Down Expand Up @@ -744,6 +752,18 @@
<header class="exception">
<h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2>
<p><%= exception_message %></p>
<% unless active_support_actions.empty? %>
<div class='fix-actions'>
<% active_support_actions.each do |action, _| %>
<form class="button_to" method="post" action="<%= action_dispatch_action_endpoint %>">
<input type="submit" value="<%= action %>">
<input type="hidden" name="action" value="<%= action %>">
<input type="hidden" name="error" value="<%= exception_type %>">
<input type="hidden" name="location" value="<%= request_path %>">
</form>
<% end %>
</div>
<% end %>
</header>
</div>

Expand Down
38 changes: 38 additions & 0 deletions spec/better_errors/error_page_spec.rb
Expand Up @@ -37,6 +37,44 @@ module BetterErrors
expect(response).to have_tag('.exception h2', /ZeroDivisionError/)
end

context 'when ActiveSupport::ActionableError is available' do
before do
skip "ActiveSupport missing on this platform" unless Object.constants.include?(:ActiveSupport)
skip "ActionableError missing on this platform" unless ActiveSupport.constants.include?(:ActionableError)
end

context 'when ActiveSupport provides one or more actions for this error type' do
let(:exception_class) {
Class.new(StandardError) do
include ActiveSupport::ActionableError

action "Do a thing" do
puts "Did a thing"
end
end
}
let(:exception) { exception_binding.eval("raise exception_class") rescue $! }

it "includes a fix-action form for each action" do
expect(response).to have_tag('.fix-actions') do
with_tag('form.button_to')
with_tag('form.button_to input[type=submit][value="Do a thing"]')
end
end
end

context 'when ActiveSupport does not provide any actions for this error type' do
let(:exception_class) {
Class.new(StandardError)
}
let(:exception) { exception_binding.eval("raise exception_class") rescue $! }

it "does not include a fix-action form" do
expect(response).not_to have_tag('.fix-actions')
end
end
end

context "variable inspection" do
let(:exception) { exception_binding.eval("raise") rescue $! }

Expand Down

0 comments on commit 448c9f2

Please sign in to comment.