Fix for returned status code and .gitignore

For this purposes I added addiitional processing of original
exceptions at wsme/wsmeext/pecan.py. For exception's validation
special validator was added to wsme/wsmeext/utils.py. Also
functionality was reworked to be compatible with python3.3

Fixes bug#1214073
Change-Id: Ib1cd0b274bda11f62298848ebcd55b3f6641757c
This commit is contained in:
119Vik 2013-08-21 11:59:39 +03:00
parent cfaaa4f068
commit 651ad18bdd
6 changed files with 133 additions and 10 deletions

2
.gitignore vendored
View File

@ -17,3 +17,5 @@ dist
doc/_build
d2to1-*.egg
WSME.egg-info/

View File

@ -19,6 +19,24 @@ class Book(Base):
author = wsattr('Author')
class BookNotFound(Exception):
message = "Book with ID={id} Not Found"
code = 404
def __init__(self, id):
message = self.message.format(id=id)
super(BookNotFound, self).__init__(message)
class NonHttpException(Exception):
message = "Internal Exception for Book ID={id}"
code = 684
def __init__(self, id):
message = self.message.format(id=id)
super(NonHttpException, self).__init__(message)
class BooksController(RestController):
@wsmeext.pecan.wsexpose(Book, int, int)
@ -71,6 +89,12 @@ class AuthorsController(RestController):
if id == 999:
raise wsme.exc.ClientSideError('Wrong ID')
if id == 998:
raise BookNotFound(id)
if id == 997:
raise NonHttpException(id)
if id == 911:
return wsme.api.Response(Author(),
status_code=401)

View File

@ -1,7 +1,15 @@
from six.moves import http_client
from test.tests import FunctionalTest
import json
import pecan
used_status_codes = [400, 401, 404, 500]
http_response_messages = {
code: '{} {}'.format(code, status)
for code, status in http_client.responses.iteritems()
if code in used_status_codes
}
class TestWS(FunctionalTest):
@ -70,12 +78,14 @@ class TestWS(FunctionalTest):
assert a['firstname'] == 'test'
def test_clientsideerror(self):
expected_status_code = 400
expected_status = http_response_messages[expected_status_code]
res = self.app.get(
'/authors/999.json',
expect_errors=True
)
print res
self.assertEqual(res.status, '400 Bad Request')
self.assertEqual(res.status, expected_status)
a = json.loads(res.body)
print a
assert a['faultcode'] == 'Client'
@ -85,29 +95,77 @@ class TestWS(FunctionalTest):
expect_errors=True
)
print res
self.assertEqual(res.status, '400 Bad Request')
self.assertEqual(res.status, expected_status)
assert '<faultcode>Client</faultcode>' in res.body
def test_custom_clientside_error(self):
expected_status_code = 404
expected_status = http_response_messages[expected_status_code]
res = self.app.get(
'/authors/998.json',
expect_errors=True
)
print res
self.assertEqual(res.status, expected_status)
a = json.loads(res.body)
print a
assert a['faultcode'] == 'Server'
res = self.app.get(
'/authors/998.xml',
expect_errors=True
)
print res
self.assertEqual(res.status, expected_status)
assert '<faultcode>Server</faultcode>' in res.body
def test_custom_non_http_clientside_error(self):
expected_status_code = 500
expected_status = http_response_messages[expected_status_code]
res = self.app.get(
'/authors/997.json',
expect_errors=True
)
print res
self.assertEqual(res.status, expected_status)
a = json.loads(res.body)
print a
assert a['faultcode'] == 'Server'
res = self.app.get(
'/authors/997.xml',
expect_errors=True
)
print res
self.assertEqual(res.status, expected_status)
assert '<faultcode>Server</faultcode>' in res.body
def test_non_default_response(self):
expected_status_code = 401
expected_status = http_response_messages[expected_status_code]
res = self.app.get(
'/authors/911.json',
expect_errors=True
)
self.assertEqual(res.status_int, 401)
self.assertEqual(res.status, '401 Unauthorized')
self.assertEqual(res.status_int, expected_status_code)
self.assertEqual(res.status, expected_status)
def test_serversideerror(self):
expected_status_code = 500
expected_status = http_response_messages[expected_status_code]
res = self.app.get('/divide_by_zero.json', expect_errors=True)
self.assertEqual(res.status, '500 Internal Server Error')
self.assertEqual(res.status, expected_status)
a = json.loads(res.body)
print a
assert a['faultcode'] == 'Server'
assert a['debuginfo'] is None
def test_serversideerror_with_debug(self):
expected_status_code = 500
expected_status = http_response_messages[expected_status_code]
pecan.set_config({'wsme': {'debug': True}})
res = self.app.get('/divide_by_zero.json', expect_errors=True)
self.assertEqual(res.status, '500 Internal Server Error')
self.assertEqual(res.status, expected_status)
a = json.loads(res.body)
print a
assert a['faultcode'] == 'Server'

View File

@ -11,6 +11,8 @@ import wsme.rest.xml
import pecan
from wsmeext.utils import is_valid_code
class JSonRenderer(object):
def __init__(self, path, extra_vars):
@ -76,14 +78,24 @@ def wsexpose(*args, **kwargs):
result = result.obj
except:
data = wsme.api.format_exception(
sys.exc_info(),
pecan.conf.get('wsme', {}).get('debug', False)
)
try:
exception_info = sys.exc_info()
orig_exception = exception_info[1]
orig_code = getattr(orig_exception, 'code', None)
data = wsme.api.format_exception(
exception_info,
pecan.conf.get('wsme', {}).get('debug', False)
)
finally:
del exception_info
if data['faultcode'] == 'Client':
pecan.response.status = 400
elif orig_code and is_valid_code(orig_code):
pecan.response.status = orig_code
else:
pecan.response.status = 500
return data
if funcdef.return_type is None:

View File

@ -0,0 +1,16 @@
from wsmeext.utils import is_valid_code
class TestUtils():
def test_validator_with_valid_code(self):
valid_code = 404
assert is_valid_code(valid_code), "Valid status code not detected"
def test_validator_with_invalid_int_code(self):
invalid_int_code = 648
assert not is_valid_code(invalid_int_code), "Invalid status code not detected"
def test_validator_with_invalid_str_code(self):
invalid_str_code = '404'
assert not is_valid_code(invalid_str_code), "Invalid status code not detected"

11
wsmeext/utils.py Normal file
View File

@ -0,0 +1,11 @@
"""
This File consists of utils functions used in wsmeext module.
"""
from six.moves import http_client
def is_valid_code(code_value):
"""
This function checks if incoming value in http response codes range.
"""
return code_value in http_client.responses