summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-10-08 12:04:24 -0700
committerEric Wong <normalperson@yhbt.net>2010-10-08 13:53:28 -0700
commitbfb59e0f92271f8ecb60e5b7146c1b6e656938b8 (patch)
treea241a3940c3529cf3c3b4bcb86949fd8d2f2da73
parentdc6b54edca2b69a5653eed98c14a8d4d71b3f45c (diff)
downloadrack-bfb59e0f92271f8ecb60e5b7146c1b6e656938b8.tar.gz
showexceptions: gracefully handle empty backtraces showexceptions
Some HTTP servers (e.g. Unicorn and Rainbows!) raise certain
exceptions without a backtrace[1], so avoid triggering our own
NoMethodError exception because of this.

[1] - http://git.bogomips.org/cgit/unicorn.git/commit/?id=e4256da292f9626d7dfca60e08f65651a0a9139a
-rw-r--r--lib/rack/showexceptions.rb8
-rw-r--r--test/spec_showexceptions.rb20
2 files changed, 27 insertions, 1 deletions
diff --git a/lib/rack/showexceptions.rb b/lib/rack/showexceptions.rb
index 697bc41f..26ff9239 100644
--- a/lib/rack/showexceptions.rb
+++ b/lib/rack/showexceptions.rb
@@ -195,7 +195,13 @@ TEMPLATE = <<'HTML'
   <h2><%=h exception.message %></h2>
   <table><tr>
     <th>Ruby</th>
-    <td><code><%=h frames.first.filename %></code>: in <code><%=h frames.first.function %></code>, line <%=h frames.first.lineno %></td>
+    <td>
+<% if first = frames.first %>
+      <code><%=h first.filename %></code>: in <code><%=h first.function %></code>, line <%=h frames.first.lineno %>
+<% else %>
+      unknown location
+<% end %>
+    </td>
   </tr><tr>
     <th>Web</th>
     <td><code><%=h req.request_method %> <%=h(req.host + path)%></code></td>
diff --git a/test/spec_showexceptions.rb b/test/spec_showexceptions.rb
index 82ac9184..908f7b73 100644
--- a/test/spec_showexceptions.rb
+++ b/test/spec_showexceptions.rb
@@ -20,4 +20,24 @@ describe Rack::ShowExceptions do
     res.should =~ /RuntimeError/
     res.should =~ /ShowExceptions/
   end
+
+  it "handles exceptions without a backtrace" do
+    res = nil
+
+    req = Rack::MockRequest.new(
+      Rack::ShowExceptions.new(
+        lambda{|env| raise RuntimeError, "", [] }
+    ))
+
+    lambda{
+      res = req.get("/")
+    }.should.not.raise
+
+    res.should.be.a.server_error
+    res.status.should.equal 500
+
+    res.should =~ /RuntimeError/
+    res.should =~ /ShowExceptions/
+    res.should =~ /unknown location/
+  end
 end