[web error] exception may not have a 'status' attribute, generating an AttributeError that hides the original error. Closes #3381670
--- a/web/application.py Fri Jan 17 09:06:40 2014 +0100
+++ b/web/application.py Fri Jan 17 09:07:20 2014 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -39,7 +39,7 @@
from cubicweb.web import LOGGER, component
from cubicweb.web import (
StatusResponse, DirectResponse, Redirect, NotFound, LogOut,
- RemoteCallFailed, InvalidSession, RequestError)
+ RemoteCallFailed, InvalidSession, RequestError, PublishException)
from cubicweb.web.request import CubicWebRequestBase
@@ -567,7 +567,7 @@
content = self.vreg['views'].main_template(req, template, view=errview)
except Exception:
content = self.vreg['views'].main_template(req, 'error-template')
- if getattr(ex, 'status', None) is not None:
+ if isinstance(ex, PublishException) and ex.status is not None:
req.status_out = ex.status
return content
@@ -580,11 +580,11 @@
def ajax_error_handler(self, req, ex):
req.set_header('content-type', 'application/json')
- status = ex.status
- if status is None:
- status = httplib.INTERNAL_SERVER_ERROR
+ status = httplib.INTERNAL_SERVER_ERROR
+ if isinstance(ex, PublishException) and ex.status is not None:
+ status = ex.status
+ req.status_out = status
json_dumper = getattr(ex, 'dumps', lambda : unicode(ex))
- req.status_out = status
return json_dumper()
# special case handling
--- a/web/test/unittest_application.py Fri Jan 17 09:06:40 2014 +0100
+++ b/web/test/unittest_application.py Fri Jan 17 09:07:20 2014 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -19,13 +19,15 @@
import base64, Cookie
import sys
+import httplib
from urllib import unquote
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.decorators import clear_cache, classproperty
from cubicweb import AuthenticationError, Unauthorized
-from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb import view
+from cubicweb.devtools.testlib import CubicWebTC, real_error_handling
from cubicweb.devtools.fake import FakeRequest
from cubicweb.web import LogOut, Redirect, INTERNAL_FIELD_VALUE
from cubicweb.web.views.basecontrollers import ViewController
@@ -264,6 +266,18 @@
{'login-subject': u'the value "admin" is already used, use another one'})
self.assertEqual(forminfo['values'], req.form)
+ def test_ajax_view_raise_arbitrary_error(self):
+ class ErrorAjaxView(view.View):
+ __regid__ = 'test.ajax.error'
+ def call(self):
+ raise Exception('whatever')
+ with self.temporary_appobjects(ErrorAjaxView):
+ with real_error_handling(self.app) as app:
+ req = self.request(vid='test.ajax.error')
+ req.ajax_request = True
+ page = app.handle_request(req, '')
+ self.assertEqual(httplib.INTERNAL_SERVER_ERROR,
+ req.status_out)
def _test_cleaned(self, kwargs, injected, cleaned):
req = self.request(**kwargs)
@@ -433,5 +447,6 @@
req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
self.app_handle_request(req)
+
if __name__ == '__main__':
unittest_main()