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 functools
|
||||||
import inspect
|
import inspect
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import wsme.exc
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def iswsmefunction(f):
|
def iswsmefunction(f):
|
||||||
@ -130,3 +136,27 @@ class signature(object):
|
|||||||
return func
|
return func
|
||||||
|
|
||||||
sig = signature
|
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 inspect
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -6,7 +8,7 @@ import wsme.rest.args
|
|||||||
import wsme.rest.json
|
import wsme.rest.json
|
||||||
import wsme.rest.xml
|
import wsme.rest.xml
|
||||||
|
|
||||||
pecan = sys.modules['pecan']
|
import pecan
|
||||||
|
|
||||||
|
|
||||||
class JSonRenderer(object):
|
class JSonRenderer(object):
|
||||||
@ -14,6 +16,8 @@ class JSonRenderer(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def render(self, template_path, namespace):
|
def render(self, template_path, namespace):
|
||||||
|
if 'faultcode' in namespace:
|
||||||
|
return wsme.rest.json.encode_error(None, namespace)
|
||||||
return wsme.rest.json.encode_result(
|
return wsme.rest.json.encode_result(
|
||||||
namespace['result'],
|
namespace['result'],
|
||||||
namespace['datatype']
|
namespace['datatype']
|
||||||
@ -25,6 +29,8 @@ class XMLRenderer(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def render(self, template_path, namespace):
|
def render(self, template_path, namespace):
|
||||||
|
if 'faultcode' in namespace:
|
||||||
|
return wsme.rest.xml.encode_error(None, namespace)
|
||||||
return wsme.rest.xml.encode_result(
|
return wsme.rest.xml.encode_result(
|
||||||
namespace['result'],
|
namespace['result'],
|
||||||
namespace['datatype']
|
namespace['datatype']
|
||||||
@ -52,11 +58,20 @@ def wsexpose(*args, **kwargs):
|
|||||||
funcdef.resolve_types(wsme.types.registry)
|
funcdef.resolve_types(wsme.types.registry)
|
||||||
|
|
||||||
def callfunction(self, *args, **kwargs):
|
def callfunction(self, *args, **kwargs):
|
||||||
args, kwargs = wsme.rest.args.get_args(
|
try:
|
||||||
funcdef, args, kwargs,
|
args, kwargs = wsme.rest.args.get_args(
|
||||||
pecan.request.body, pecan.request.content_type
|
funcdef, args, kwargs,
|
||||||
)
|
pecan.request.body, pecan.request.content_type
|
||||||
result = f(self, *args, **kwargs)
|
)
|
||||||
|
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(
|
return dict(
|
||||||
datatype=funcdef.return_type,
|
datatype=funcdef.return_type,
|
||||||
result=result
|
result=result
|
||||||
|
29
wsme/root.py
29
wsme/root.py
@ -1,6 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from six import u, b
|
from six import u, b
|
||||||
@ -12,6 +11,7 @@ from wsme.exc import ClientSideError, MissingArgument, UnknownFunction
|
|||||||
from wsme.protocol import getprotocol
|
from wsme.protocol import getprotocol
|
||||||
from wsme.rest import scan_api
|
from wsme.rest import scan_api
|
||||||
from wsme import spore
|
from wsme import spore
|
||||||
|
import wsme.api
|
||||||
import wsme.types
|
import wsme.types
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -200,7 +200,7 @@ class WSRoot(object):
|
|||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
e = sys.exc_info()[1]
|
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):
|
if isinstance(e, ClientSideError):
|
||||||
request.client_errorcount += 1
|
request.client_errorcount += 1
|
||||||
else:
|
else:
|
||||||
@ -292,7 +292,7 @@ class WSRoot(object):
|
|||||||
res.status = protocol.get_response_status(request)
|
res.status = protocol.get_response_status(request)
|
||||||
res_content_type = protocol.get_response_contenttype(request)
|
res_content_type = protocol.get_response_contenttype(request)
|
||||||
except Exception:
|
except Exception:
|
||||||
infos = self._format_exception(sys.exc_info())
|
infos = wsme.api.format_exception(sys.exc_info(), self._debug)
|
||||||
request.server_errorcount += 1
|
request.server_errorcount += 1
|
||||||
res.text = protocol.encode_error(context, infos)
|
res.text = protocol.encode_error(context, infos)
|
||||||
res.status = 500
|
res.status = 500
|
||||||
@ -325,29 +325,6 @@ class WSRoot(object):
|
|||||||
return f, fdef, args
|
return f, fdef, args
|
||||||
raise UnknownFunction('/'.join(path))
|
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):
|
def _html_format(self, content, content_types):
|
||||||
try:
|
try:
|
||||||
from pygments import highlight
|
from pygments import highlight
|
||||||
|
Loading…
x
Reference in New Issue
Block a user