I just noticed something I think is interesting and wanted to see what
everyone felt about it. Using a quick and dirty scaffold to create a
resource, I found that if I hit a show url, with an invalid id, it
will throw an exception in html instead of xml.
Here is how you repeat this.
$ rails testing_rest
$ cd testing_rest
$ ./script/generate scaffold person name:string
$ rake db:migrate
$ ./script/server
From another window
$ curl -i -H "Accept: application/xml" -H "Content-Type:
application/
xml" http://127.0.0.1:3000/people
So far, so good. I was returned an empty array in xml
HTTP/1.1 200 OK
...
Content-Type: application/xml; charset=utf-8
...
<?xml version="1.0" encoding="UTF-8"?>
<nil-classes type="array"/>
-----
Now, I send over a request for a person that doesn''t exist.
$ curl -i -H "Accept: application/xml" -H "Content-Type:
application/
xml" http://127.0.0.1:3000/people/1
I get back a full html debug output in html. Yuck!
HTTP/1.1 404 Not Found
...
Content-Type: text/html; charset=utf-8
...
I chopped the content for readability, its not what matters.
----
Ok, so I''m in development mode and it will automatically assume I am
local and spit out the debug. I can handle that, although I still
don''t think it should be in html.
But, if I run db:migrate again under production and start it up (or
modify enviroment.rb), and now hit the external IP of my machine
instead of localhost, I get back the 404 page. Better, but, its still
coming back in html.
$ curl -i -H "Accept: application/xml" -H "Content-Type:
application/
xml" http://192.168.1.101:3000/people/1
lication/xml" http://192.168.247.20:3000/people/1
HTTP/1.1 404 Not Found
Connection: close
Date: Fri, 29 Feb 2008 02:24:02 GMT
Set-Cookie:
_testing_rest_session=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
%250ASGFzaHsABjoKQHVzZWR7AA%253D%253D--
d1e3f66166f02f6c78f45395f7c0186d7ab9dcd9; path=/
Status: 404 Not Found
Cache-Control: no-cache
Server: Mongrel 1.1.3
Content-Type: text/html; charset=utf-8
Content-Length: 947
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en">
...
-------
My question is, shouldn''t this be returning me xml? I do have a
respond_to block saying that it should spit back xml. Well, the
problem is in the way rails handles uncaught exceptions. It doesn''t
do anything with content-type from what I can see. If there is a
404.html file in public, it will render it as html. If you don''t have
a 404.html file, it will simply send back a head with 404 as the
response. However, it still shows content-type as xml.
So, I guess I have three choices. The first one is to catch that
exception in my action. The second one is to create a plugin. The
third is to just not care that I am sending back html to my xml
clients. I chose the plugin.
What are you all doing? Does it matter that I am sending content-type
html to an xml client? What about rss, javascript, etc....
BTW - here is my plugin. Nothing special I just add the alternate
formats I want to the ALT_FORMATS array. I also have access to a
template to render instead of a static html file in public. Not sure
if that gives me anything great, just how I chose to do it at the
time.
Thoughts??
-Dusty Doris
--------
module MyExceptionHandler
DEFAULT_CODES = {
''ActionController::RoutingError'' => :not_found,
''ActionController::UnknownAction'' => :not_found,
''ActiveRecord::RecordNotFound'' => :not_found,
''ActiveRecord::StaleObjectError'' => :conflict,
''ActiveRecord::RecordInvalid'' =>
:unprocessable_entity,
''ActiveRecord::RecordNotSaved'' =>
:unprocessable_entity,
''ActionController::MethodNotAllowed'' =>
:method_not_allowed,
''ActionController::NotImplemented'' =>
:not_implemented,
''ActionController::InvalidAuthenticityToken''
=> :unprocessable_entity
}
ALT_FORMATS = [:xml, :json, :js, :rss, :atom, :text]
def rescue_action_in_public(exception)
@exception = exception
respond_to do |format|
format.html do
render :template => "exceptions/#{return_code.to_s}",
:layout => "exceptions",
:status => return_code
end
ALT_FORMATS.each do |f|
format.send(f) { head :status => return_code }
end
end
end
def rescue_action_locally(exception)
respond_to do |format|
format.html do
add_variables_to_assigns
@template.instance_variable_set("@exception", exception)
@template.instance_variable_set("@rescues_path",
File.dirname(rescues_path("stub")))
@template.send!(:assign_variables_from_controller)
@template.instance_variable_set("@contents",
@template.render_file(template_path_for_local_rescue(exception),
false))
response.content_type = Mime::HTML
render_for_file(rescues_path("layout"),
response_code_for_rescue(exception))
end
ALT_FORMATS.each do |f|
format.send(f) { head :status => return_code }
end
end
end
private
def return_code
DEFAULT_CODES[@exception.class.to_s] || :internal_server_error
end
end
With a little
require ''my_exception_handler''
ActionController::Base.send :include, MyExceptionHandler
ActionController::Base.consider_all_requests_local = false
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Ilan Berci
2008-Feb-29 02:52 UTC
Re: default exception doesn''t render with correct content ty
dusty wrote:> > require ''my_exception_handler'' > ActionController::Base.send :include, MyExceptionHandler > ActionController::Base.consider_all_requests_local = falsesomething like the following will also work.. class Application < ActionController::Base around_filter :catch_exceptions def catch_exceptions begin yield rescue Exception => e render :xml => e.message, :status => 500 end end end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks for the reply. That would be much easier. The filters are nice, unfortunately, it doesn''t catch things like ActionController::RoutingErrors. At least its not for me. It does catch things like notfound errors within an action though. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Ilan Berci
2008-Feb-29 03:35 UTC
Re: default exception doesn''t render with correct content ty
dusty wrote:> Thanks for the reply. That would be much easier. The filters are > nice, unfortunately, it doesn''t catch things like > ActionController::RoutingErrors. At least its not for me. It does > catch things like notfound errors within an action though.You are right, it won''t catch routing errors as they are thrown before the surround_filters get a chance to party :( ilan -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---