webob.exc.WSGIHTTPException assumes html response body

41 views
Skip to first unread message

Chris

unread,
Sep 29, 2009, 9:14:57 AM9/29/09
to pylons-devel
Hi

We are creating a web service using Pyons that uses XML as the primary
response content type. We have had some trouble when using abort()
because it raises a webob.exc.WSGIHTTPException which has a HTML
response as it's default body.

The workaround we have implemented overrides _inspect_call() in
base.py like this

def _inspect_call(self, func):
result = super(BaseController, self)._inspect_call(func)
if hasattr(result,'empty_body'):
result.empty_body = True

return result


Perhaps it should be the default to always set empty_body to True when
a WSGIHTTPException is raised or when it is caught.

Christoph Haas

unread,
Sep 30, 2009, 10:56:02 AM9/30/09
to pylons...@googlegroups.com
Chris schrieb:

I would like to chime in because I have a similar problem. When a user
requests an image in my application that isn't available then I'd like to
return a dummy image along with an HTTP response code 404. But as soon as I
set the status to 404 or even abort(404) then no matter what I try I always
get an HTTP response. Overriding functions isn't really my preferred way
here either. It's one of the few occassions where the framework got in my
way. :)

Cheers
Christoph


signature.asc

Qiangning Hong

unread,
Sep 30, 2009, 11:18:47 AM9/30/09
to pylons...@googlegroups.com

I've made a json_abort function to raise customized webob.exc in my lib/util.py:

import simplejson as json

def json_abort(status_code=None, detail="", headers=None, comment=None):
"""Same with pylons.controllers.util.abort but with json output."""

exc_class = status_map[status_code]
class JsonException(exc_class):
def __call__(self, environ, start_response):
self.content_type = 'text/javascript; charset=utf-8'
self.body = json.dumps(self.detail)
return Response.__call__(self, environ, start_response)
exc = JsonException(detail=detail, headers=headers, comment=comment)

log.debug("Aborting request with JSON response, status: %s,
detail: %r, headers: %r, "
"comment: %r", status_code, detail, headers, comment)
request.environ['pylons.status_code_redirect'] = True # skip err doc
raise exc.exception

so that, I can just call json_abort(404, {'reason': "resource not
found"}) in my controllers and users will receive a 404 error response
with a json documenting the reason in it.


--
Qiangning Hong
http://www.douban.com/people/hongqn/

Chris

unread,
Oct 1, 2009, 9:24:52 AM10/1/09
to pylons-devel
Originally we were planning to get round this problem by just changing
error_document_template in the error controller to be XML rarther than
HTML. This is no good in our case because we have custom XML schema
validation middleware that rejects the response object created by abort
() before it gets to the statusCodeRedirect middleware. Perhaps this
approach could help you. I am making the assumption that you have
mistaken where the HTML is coming from, if this is incorrect I am
sorry.
>  signature.asc
> < 1KViewDownload

Ian Bicking

unread,
Oct 5, 2009, 9:02:19 PM10/5/09
to pylons...@googlegroups.com
There's a little bug that keeps this from working:

  raise webob.exc.HTTPNotFound('blah blah', content_type='application/xml')

(fixed on trunk though)

But you should be able to do this:

e = webob.exc.HTTPNotFound()
e.body = '<blah />'
e.content_type = 'application/xml'
raise e # or e.exception on python2.4

Now... if "html" and "*/*" aren't in the HTTP Accept header, the automatic body *should* be plain text, not HTML (but it won't be XML, if that's what you want).

It's also possible that Pylons' status code redirect thing is rewriting the error response; so if this doesn't work then the problem is probably there.

Reply all
Reply to author
Forward
0 new messages