# HG changeset patch # User Adrien Di Mascio # Date 1434470518 -7200 # Node ID 0bbd211cf4d756a15c8cc7c0826d6f17acf58ee4 # Parent f9b06d03859f30bbc7c1b2f837a84942480ce447 [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'))`` diff -r f9b06d03859f -r 0bbd211cf4d7 web/views/json.py --- 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), + }) diff -r f9b06d03859f -r 0bbd211cf4d7 web/views/management.py --- 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'

%s

' % 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'
%s
'