Add improved support for HTTP response codes in TG 1.x apps.
Change-Id: I829ab360e13ae88a47e810079c739eac1d925139
This commit is contained in:
parent
d8a70a300e
commit
0aba00b1ef
@ -4,6 +4,7 @@ from wsmeext.tg11 import wsexpose, wsvalidate
|
|||||||
import wsmeext.tg1
|
import wsmeext.tg1
|
||||||
|
|
||||||
from turbogears.controllers import RootController
|
from turbogears.controllers import RootController
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
@ -43,9 +44,14 @@ class Root(RootController):
|
|||||||
def multiply(self, a, b):
|
def multiply(self, a, b):
|
||||||
return 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
|
from turbogears import testutil, config, startup
|
||||||
|
|
||||||
@ -108,6 +114,31 @@ class TestController(unittest.TestCase):
|
|||||||
print response
|
print response
|
||||||
assert response.body == "<result>50</result>"
|
assert response.body == "<result>50</result>"
|
||||||
|
|
||||||
|
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 == ("<error><faultcode>Server</faultcode>"
|
||||||
|
"<faultstring>(400, 'Cannot divide by zero!')"
|
||||||
|
"</faultstring><debuginfo /></error>")
|
||||||
|
|
||||||
def test_soap_wsdl(self):
|
def test_soap_wsdl(self):
|
||||||
ts = test_soap.TestSOAP('test_wsdl')
|
ts = test_soap.TestSOAP('test_wsdl')
|
||||||
ts.app = self.app
|
ts.app = self.app
|
||||||
|
@ -2,6 +2,7 @@ import wsmeext.tg15
|
|||||||
from wsme import WSRoot
|
from wsme import WSRoot
|
||||||
|
|
||||||
from turbogears.controllers import RootController
|
from turbogears.controllers import RootController
|
||||||
|
import cherrypy
|
||||||
|
|
||||||
from wsmeext.tests import test_soap
|
from wsmeext.tests import test_soap
|
||||||
|
|
||||||
@ -35,6 +36,13 @@ class Root(RootController):
|
|||||||
def multiply(self, a, b):
|
def multiply(self, a, b):
|
||||||
return 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
|
from turbogears import testutil
|
||||||
|
|
||||||
@ -91,6 +99,31 @@ class TestController(testutil.TGTest):
|
|||||||
print response
|
print response
|
||||||
assert response.body == "<result>50</result>"
|
assert response.body == "<result>50</result>"
|
||||||
|
|
||||||
|
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 == ("<error><faultcode>Server</faultcode>"
|
||||||
|
"<faultstring>(400, 'Cannot divide by zero!')"
|
||||||
|
"</faultstring><debuginfo /></error>")
|
||||||
|
|
||||||
def test_soap_wsdl(self):
|
def test_soap_wsdl(self):
|
||||||
wsdl = self.app.get('/ws/api.wsdl').body
|
wsdl = self.app.get('/ws/api.wsdl').body
|
||||||
print wsdl
|
print wsdl
|
||||||
|
@ -4,15 +4,17 @@ except ImportError:
|
|||||||
import simplejson as json # noqa
|
import simplejson as json # noqa
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
import sys
|
||||||
|
|
||||||
import cherrypy
|
import cherrypy
|
||||||
import webob
|
import webob
|
||||||
from turbogears import expose
|
from turbogears import expose, util
|
||||||
|
|
||||||
from wsme.rest import validate as wsvalidate
|
from wsme.rest import validate as wsvalidate
|
||||||
import wsme.api
|
import wsme.api
|
||||||
import wsme.rest.args
|
import wsme.rest.args
|
||||||
import wsme.rest.json
|
import wsme.rest.json
|
||||||
|
from wsmeext.utils import is_valid_code
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
@ -55,7 +57,35 @@ def wsexpose(*args, **kwargs):
|
|||||||
)
|
)
|
||||||
if funcdef.pass_request:
|
if funcdef.pass_request:
|
||||||
kwargs[funcdef.pass_request] = cherrypy.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(
|
return dict(
|
||||||
datatype=funcdef.return_type,
|
datatype=funcdef.return_type,
|
||||||
result=result
|
result=result
|
||||||
@ -116,7 +146,6 @@ class Controller(object):
|
|||||||
cherrypy.response.status = res.status
|
cherrypy.response.status = res.status
|
||||||
return res.body
|
return res.body
|
||||||
|
|
||||||
|
|
||||||
import wsme.rest
|
import wsme.rest
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user