I've been trying to fix a bug in the Rails app I'm developing, and I keep getting a blank screen with no errors. I haven't found anything helpful in development.log
, either (though it does show queries being run and such).
Finally, I started to wonder if it's somehow set not to show errors anymore. I tried commenting out a necessary route, and sure enough, I got a blank page instead of the error and stack trace I expected.
What might cause this?
(I wondered if maybe I'm accidentally running production mode and errors aren't supposed开发者_JS百科 to show then, but development.log
is being appended, and if I open script/console
and echo ENV['RAILS_ENV']
, it says development.)
How I broke it, how I fixed it, and how I learned my lesson
I figured out the problem while lying in bed this morning, and it boils down to "I did something stupid." (Doesn't it always?)
The smart part
First, the smart part: I followed some neat advice about setting up access control and permissions. It gives you some great a great syntax for saying what's allowed, like this:
<%= link_to 'Delete', @photo, :confirm => "Really delete this photo?", :method => :delete if current_user.can_delete?(@photo)%>
(The current_user
bit comes from the Restful-authentication plugin.)
The author also shows how to handle the case where a user tries to type in a URL for which you haven't given them a link. It involves setting up a special exception class, which subclasses StandardError
, and handling it with something like a 401.html
- access denied.
The stupid part
What I did that was stupid was I followed his example blindly. He shows this:
def rescue_action(e)
case e
when SecurityTransgression
head :forbidden
end
end
...which handles the SecurityTransgression
fine, but breaks the default error handling in Rails. (I'm sure the author knows this and dealt with it, but he didn't discuss it.)
The solution
The solution was to add two lines:
def rescue_action(e)
case e
when SecurityTransgression
head :forbidden
else
super
end
end
The "else super" part says "if I haven't specified anything here, let the inherited rescue_action
method handle it."
Now I'm getting the correct stack trace for my original problem, and will proceed to troubleshoot it.
The lesson: be careful when you mess with exception handling, and make sure the default case still works!
Check your default route and make sure the view isn't just empty.
精彩评论