diff --git a/tests/test_tg1.py b/tests/test_tg1.py
index 5a4f593..f5a27a9 100644
--- a/tests/test_tg1.py
+++ b/tests/test_tg1.py
@@ -4,6 +4,7 @@ from wsmeext.tg11 import wsexpose, wsvalidate
import wsmeext.tg1
from turbogears.controllers import RootController
+import cherrypy
import unittest
@@ -43,9 +44,14 @@ class Root(RootController):
def multiply(self, a, b):
return a * b
- sub = Subcontroller()
+ @wsexpose(int)
+ @wsvalidate(int, int)
+ def divide(self, a, b):
+ if b == 0:
+ raise cherrypy.HTTPError(400, 'Cannot divide by zero!')
+ return a / b
-import cherrypy
+ sub = Subcontroller()
from turbogears import testutil, config, startup
@@ -108,6 +114,31 @@ class TestController(unittest.TestCase):
print response
assert response.body == "50"
+ def test_custom_clientside_error(self):
+ response = self.app.post(
+ "/divide",
+ simplejson.dumps({'a': 5, 'b': 0}),
+ {'Content-Type': 'application/json', 'Accept': 'application/json'},
+ expect_errors=True
+ )
+ assert response.status_int == 400
+ assert simplejson.loads(response.body) == {
+ "debuginfo": None,
+ "faultcode": "Server",
+ "faultstring": "(400, 'Cannot divide by zero!')"
+ }
+
+ response = self.app.post(
+ "/divide",
+ simplejson.dumps({'a': 5, 'b': 0}),
+ {'Content-Type': 'application/json', 'Accept': 'text/xml'},
+ expect_errors=True
+ )
+ assert response.status_int == 400
+ assert response.body == ("Server"
+ "(400, 'Cannot divide by zero!')"
+ "")
+
def test_soap_wsdl(self):
ts = test_soap.TestSOAP('test_wsdl')
ts.app = self.app
diff --git a/tests/test_tg15.py b/tests/test_tg15.py
index 61f9127..36c6860 100644
--- a/tests/test_tg15.py
+++ b/tests/test_tg15.py
@@ -2,6 +2,7 @@ import wsmeext.tg15
from wsme import WSRoot
from turbogears.controllers import RootController
+import cherrypy
from wsmeext.tests import test_soap
@@ -35,6 +36,13 @@ class Root(RootController):
def multiply(self, a, b):
return a * b
+ @wsmeext.tg15.wsexpose(int)
+ @wsmeext.tg15.wsvalidate(int, int)
+ def divide(self, a, b):
+ if b == 0:
+ raise cherrypy.HTTPError(400, 'Cannot divide by zero!')
+ return a / b
+
from turbogears import testutil
@@ -91,6 +99,31 @@ class TestController(testutil.TGTest):
print response
assert response.body == "50"
+ def test_custom_clientside_error(self):
+ response = self.app.post(
+ "/divide",
+ simplejson.dumps({'a': 5, 'b': 0}),
+ {'Content-Type': 'application/json', 'Accept': 'application/json'},
+ expect_errors=True
+ )
+ assert response.status_int == 400
+ assert simplejson.loads(response.body) == {
+ "debuginfo": None,
+ "faultcode": "Server",
+ "faultstring": "(400, 'Cannot divide by zero!')"
+ }
+
+ response = self.app.post(
+ "/divide",
+ simplejson.dumps({'a': 5, 'b': 0}),
+ {'Content-Type': 'application/json', 'Accept': 'text/xml'},
+ expect_errors=True
+ )
+ assert response.status_int == 400
+ assert response.body == ("Server"
+ "(400, 'Cannot divide by zero!')"
+ "")
+
def test_soap_wsdl(self):
wsdl = self.app.get('/ws/api.wsdl').body
print wsdl
diff --git a/wsmeext/tg1.py b/wsmeext/tg1.py
index 70582d2..16a7bdf 100644
--- a/wsmeext/tg1.py
+++ b/wsmeext/tg1.py
@@ -4,15 +4,17 @@ except ImportError:
import simplejson as json # noqa
import functools
+import sys
import cherrypy
import webob
-from turbogears import expose
+from turbogears import expose, util
from wsme.rest import validate as wsvalidate
import wsme.api
import wsme.rest.args
import wsme.rest.json
+from wsmeext.utils import is_valid_code
import inspect
@@ -55,7 +57,35 @@ def wsexpose(*args, **kwargs):
)
if funcdef.pass_request:
kwargs[funcdef.pass_request] = cherrypy.request
- result = f(self, *args, **kwargs)
+ try:
+ result = f(self, *args, **kwargs)
+ except:
+ try:
+ exception_info = sys.exc_info()
+ orig_exception = exception_info[1]
+ if isinstance(orig_exception, cherrypy.HTTPError):
+ orig_code = getattr(orig_exception, 'status', None)
+ else:
+ orig_code = getattr(orig_exception, 'code', None)
+ data = wsme.api.format_exception(exception_info)
+ finally:
+ del exception_info
+
+ cherrypy.response.status = 500
+ if data['faultcode'] == 'client':
+ cherrypy.response.status = 400
+ elif orig_code and is_valid_code(orig_code):
+ cherrypy.response.status = orig_code
+
+ accept = cherrypy.request.headers.get('Accept', "").lower()
+ accept = util.simplify_http_accept_header(accept)
+
+ decorators = {'text/xml': wsme.rest.xml.encode_error}
+ return decorators.get(
+ accept,
+ wsme.rest.json.encode_error
+ )(None, data)
+
return dict(
datatype=funcdef.return_type,
result=result
@@ -116,7 +146,6 @@ class Controller(object):
cherrypy.response.status = res.status
return res.body
-
import wsme.rest