[views] implement a custom json error view
If the client asked for ``(e)jsonexport`` view, answer
him with a json response rather than an error formatted
in a big HTML blob.
add a custom _requested_vid predicate. In cw 3.21, it will
be deprecated in favor of ``match_form_params(vid=('jsonexport', 'ejsonexport'))``
--- a/web/views/json.py Wed May 13 17:49:45 2015 +0200
+++ b/web/views/json.py Tue Jun 16 18:01:58 2015 +0200
@@ -20,11 +20,13 @@
__docformat__ = "restructuredtext en"
_ = unicode
+from cubicweb.uilib import rest_traceback
+
from cubicweb.utils import json_dumps
-from cubicweb.predicates import any_rset, empty_rset
+from cubicweb.predicates import ExpectedValuePredicate, any_rset, empty_rset
from cubicweb.view import EntityView, AnyRsetView
from cubicweb.web.application import anonymized_request
-from cubicweb.web.views import basecontrollers
+from cubicweb.web.views import basecontrollers, management
class JsonpController(basecontrollers.ViewController):
"""The jsonp controller is the same as a ViewController but :
@@ -119,3 +121,31 @@
})
entities.append(entity)
self.wdata(entities)
+
+
+class _requested_vid(ExpectedValuePredicate):
+ """predicate that checks vid parameter value
+
+ It differs from ``match_view`` in that it doesn't expect a ``view``
+ parameter to be given to ``select`` but will rather check
+ ``req.form['vid']`` to match expected vid.
+ """
+ def __call__(self, cls, req, rset=None, **kwargs):
+ return req.form.get('vid') in self.expected
+
+
+class JsonErrorView(JsonMixIn, management.ErrorView):
+ """custom error view selected when client asks for a json view
+
+ The returned json object will contain err / traceback informations.
+ """
+ __select__ = (management.ErrorView.__select__ &
+ _requested_vid('jsonexport', 'ejsonexport'))
+
+ def call(self):
+ errmsg, exclass, excinfo = self._excinfo()
+ self.wdata({
+ 'errmsg': errmsg,
+ 'exclass': exclass,
+ 'traceback': rest_traceback(excinfo, errmsg),
+ })
--- a/web/views/management.py Wed May 13 17:49:45 2015 +0200
+++ b/web/views/management.py Tue Jun 16 18:01:58 2015 +0200
@@ -105,19 +105,24 @@
"""
return self._cw._('an error occurred')
+ def _excinfo(self):
+ req = self._cw
+ ex = req.data.get('ex')
+ excinfo = req.data.get('excinfo')
+ if 'errmsg' in req.data:
+ errmsg = req.data['errmsg']
+ exclass = None
+ else:
+ errmsg = exc_message(ex, req.encoding)
+ exclass = ex.__class__.__name__
+ return errmsg, exclass, excinfo
+
def call(self):
req = self._cw.reset_headers()
w = self.w
- ex = req.data.get('ex')#_("unable to find exception information"))
- excinfo = req.data.get('excinfo')
title = self._cw._('an error occurred')
w(u'<h2>%s</h2>' % title)
- if 'errmsg' in req.data:
- ex = req.data['errmsg']
- exclass = None
- else:
- exclass = ex.__class__.__name__
- ex = exc_message(ex, req.encoding)
+ ex, exclass, excinfo = self._excinfo()
if excinfo is not None and self._cw.vreg.config['print-traceback']:
if exclass is None:
w(u'<div class="tb">%s</div>'