Allow adapters to use the format_exception function, and use it in the Pecan adapter. /\!\ the response status is not properly changed by the decorator yet.
This commit is contained in:
parent
bd95dafa7b
commit
4edbd4bb8f
30
wsme/api.py
30
wsme/api.py
@ -1,5 +1,11 @@
|
||||
import traceback
|
||||
import functools
|
||||
import inspect
|
||||
import logging
|
||||
|
||||
import wsme.exc
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def iswsmefunction(f):
|
||||
@ -130,3 +136,27 @@ class signature(object):
|
||||
return func
|
||||
|
||||
sig = signature
|
||||
|
||||
|
||||
def format_exception(excinfo, debug=False):
|
||||
"""Extract informations that can be sent to the client."""
|
||||
error = excinfo[1]
|
||||
if isinstance(error, wsme.exc.ClientSideError):
|
||||
r = dict(faultcode="Client",
|
||||
faultstring=error.faultstring)
|
||||
log.warning("Client-side error: %s" % r['faultstring'])
|
||||
r['debuginfo'] = None
|
||||
return r
|
||||
else:
|
||||
faultstring = str(error)
|
||||
debuginfo = "\n".join(traceback.format_exception(*excinfo))
|
||||
|
||||
log.error('Server-side error: "%s". Detail: \n%s' % (
|
||||
faultstring, debuginfo))
|
||||
|
||||
r = dict(faultcode="Server", faultstring=faultstring)
|
||||
if debug:
|
||||
r['debuginfo'] = debuginfo
|
||||
else:
|
||||
r['debuginfo'] = None
|
||||
return r
|
||||
|
@ -1,3 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
@ -6,7 +8,7 @@ import wsme.rest.args
|
||||
import wsme.rest.json
|
||||
import wsme.rest.xml
|
||||
|
||||
pecan = sys.modules['pecan']
|
||||
import pecan
|
||||
|
||||
|
||||
class JSonRenderer(object):
|
||||
@ -14,6 +16,8 @@ class JSonRenderer(object):
|
||||
pass
|
||||
|
||||
def render(self, template_path, namespace):
|
||||
if 'faultcode' in namespace:
|
||||
return wsme.rest.json.encode_error(None, namespace)
|
||||
return wsme.rest.json.encode_result(
|
||||
namespace['result'],
|
||||
namespace['datatype']
|
||||
@ -25,6 +29,8 @@ class XMLRenderer(object):
|
||||
pass
|
||||
|
||||
def render(self, template_path, namespace):
|
||||
if 'faultcode' in namespace:
|
||||
return wsme.rest.xml.encode_error(None, namespace)
|
||||
return wsme.rest.xml.encode_result(
|
||||
namespace['result'],
|
||||
namespace['datatype']
|
||||
@ -52,11 +58,20 @@ def wsexpose(*args, **kwargs):
|
||||
funcdef.resolve_types(wsme.types.registry)
|
||||
|
||||
def callfunction(self, *args, **kwargs):
|
||||
args, kwargs = wsme.rest.args.get_args(
|
||||
funcdef, args, kwargs,
|
||||
pecan.request.body, pecan.request.content_type
|
||||
)
|
||||
result = f(self, *args, **kwargs)
|
||||
try:
|
||||
args, kwargs = wsme.rest.args.get_args(
|
||||
funcdef, args, kwargs,
|
||||
pecan.request.body, pecan.request.content_type
|
||||
)
|
||||
result = f(self, *args, **kwargs)
|
||||
except:
|
||||
data = wsme.api.format_exception(sys.exc_info())
|
||||
if data['faultcode'] == 'Client':
|
||||
pecan.response.status = 400
|
||||
else:
|
||||
pecan.response.status = 500
|
||||
return data
|
||||
|
||||
return dict(
|
||||
datatype=funcdef.return_type,
|
||||
result=result
|
||||
|
29
wsme/root.py
29
wsme/root.py
@ -1,6 +1,5 @@
|
||||
import logging
|
||||
import sys
|
||||
import traceback
|
||||
import weakref
|
||||
|
||||
from six import u, b
|
||||
@ -12,6 +11,7 @@ from wsme.exc import ClientSideError, MissingArgument, UnknownFunction
|
||||
from wsme.protocol import getprotocol
|
||||
from wsme.rest import scan_api
|
||||
from wsme import spore
|
||||
import wsme.api
|
||||
import wsme.types
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -200,7 +200,7 @@ class WSRoot(object):
|
||||
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
infos = self._format_exception(sys.exc_info())
|
||||
infos = wsme.api.format_exception(sys.exc_info(), self._debug)
|
||||
if isinstance(e, ClientSideError):
|
||||
request.client_errorcount += 1
|
||||
else:
|
||||
@ -292,7 +292,7 @@ class WSRoot(object):
|
||||
res.status = protocol.get_response_status(request)
|
||||
res_content_type = protocol.get_response_contenttype(request)
|
||||
except Exception:
|
||||
infos = self._format_exception(sys.exc_info())
|
||||
infos = wsme.api.format_exception(sys.exc_info(), self._debug)
|
||||
request.server_errorcount += 1
|
||||
res.text = protocol.encode_error(context, infos)
|
||||
res.status = 500
|
||||
@ -325,29 +325,6 @@ class WSRoot(object):
|
||||
return f, fdef, args
|
||||
raise UnknownFunction('/'.join(path))
|
||||
|
||||
def _format_exception(self, excinfo):
|
||||
"""Extract informations that can be sent to the client."""
|
||||
error = excinfo[1]
|
||||
if isinstance(error, ClientSideError):
|
||||
r = dict(faultcode="Client",
|
||||
faultstring=error.faultstring)
|
||||
log.warning("Client-side error: %s" % r['faultstring'])
|
||||
r['debuginfo'] = None
|
||||
return r
|
||||
else:
|
||||
faultstring = str(error)
|
||||
debuginfo = "\n".join(traceback.format_exception(*excinfo))
|
||||
|
||||
log.error('Server-side error: "%s". Detail: \n%s' % (
|
||||
faultstring, debuginfo))
|
||||
|
||||
r = dict(faultcode="Server", faultstring=faultstring)
|
||||
if self._debug:
|
||||
r['debuginfo'] = debuginfo
|
||||
else:
|
||||
r['debuginfo'] = None
|
||||
return r
|
||||
|
||||
def _html_format(self, content, content_types):
|
||||
try:
|
||||
from pygments import highlight
|
||||
|
Loading…
x
Reference in New Issue
Block a user