summary refs log tree commit
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2022-07-08 18:03:22 +0900
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2022-07-09 15:31:49 +1200
commit39776bd30e37752ec5917750297846fc82936d4f (patch)
treedcf97e9d7e19fa6be3e75d8b75a192f5fc9a6159
parent28d25c2eef9c8e4bdbe8ec3303c8bc086138981c (diff)
downloadrack-39776bd30e37752ec5917750297846fc82936d4f.tar.gz
Use Exception#detailed_message if available
Ruby 3.2 will provide `Exception#detailed_message` which returns more
informative message including hints for debugging.

https://bugs.ruby-lang.org/issues/18564

The did_you_mean gem and error_highlight gem is planned to use the
method to add their hints in Ruby 3.2. So using `Exception#message` will
not include did_you_mean and error_highlight hints.

This changeset uses `Exception#detailed_message` if available to show
exceptions.
-rw-r--r--lib/rack/show_exceptions.rb11
-rw-r--r--test/spec_show_exceptions.rb25
2 files changed, 35 insertions, 1 deletions
diff --git a/lib/rack/show_exceptions.rb b/lib/rack/show_exceptions.rb
index a89b1042..ca090a50 100644
--- a/lib/rack/show_exceptions.rb
+++ b/lib/rack/show_exceptions.rb
@@ -59,7 +59,12 @@ module Rack
     private :accepts_html?
 
     def dump_exception(exception)
-      string = "#{exception.class}: #{exception.message}\n".dup
+      if exception.respond_to?(:detailed_message)
+        message = exception.detailed_message(highlight: false)
+      else
+        message = exception.message
+      end
+      string = "#{exception.class}: #{message}\n".dup
       string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
       string
     end
@@ -231,7 +236,11 @@ module Rack
 
       <div id="summary">
         <h1><%=h exception.class %> at <%=h path %></h1>
+      <% if exception.respond_to?(:detailed_message) %>
+        <h2><%=h exception.detailed_message(highlight: false) %></h2>
+      <% else %>
         <h2><%=h exception.message %></h2>
+      <% end %>
         <table><tr>
           <th>Ruby</th>
           <td>
diff --git a/test/spec_show_exceptions.rb b/test/spec_show_exceptions.rb
index 64c5bc19..f6fc68de 100644
--- a/test/spec_show_exceptions.rb
+++ b/test/spec_show_exceptions.rb
@@ -177,4 +177,29 @@ describe Rack::ShowExceptions do
       assert_equal(expected, exc.prefers_plaintext?(env))
     end
   end
+
+  it "prefers Exception#detailed_message instead of Exception#message if available" do
+    res = nil
+
+    custom_exc_class = Class.new(RuntimeError) do
+      def detailed_message(highlight: false)
+        "detailed_message_test"
+      end
+    end
+
+    req = Rack::MockRequest.new(
+      show_exceptions(
+        lambda{|env| raise custom_exc_class }
+    ))
+
+    res = req.get("/", "HTTP_ACCEPT" => "text/html")
+
+    res.must_be :server_error?
+    res.status.must_equal 500
+
+    assert_match(res, /detailed_message_test/)
+    assert_match(res, /ShowExceptions/)
+    assert_match(res, /No GET data/)
+    assert_match(res, /No POST data/)
+  end
 end