Skip to content

Commit

Permalink
Store parsing exceptions when dealing with an unexpected status
Browse files Browse the repository at this point in the history
  • Loading branch information
epsy committed May 7, 2016
1 parent 71406a5 commit f772f25
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
12 changes: 11 additions & 1 deletion napper/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,19 @@ def __init__(self):
class Any(Exception):
def __init__(self, request, response):
self.request = request
self.response = response
self._response = response
self.status_code = request._response.status

@property
def response(self):
exc = getattr(self, '__cause__', None)
if exc is not None:
raise exc
return self._response

def __repr__(self):
return repr(self.response)

code_classes = {
1: "Informational",
2: "Success",
Expand Down
11 changes: 8 additions & 3 deletions napper/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,17 @@ async def upgraded_response(self):

@metafunc
def __await__(self):
data = yield from self.upgraded_response()
yield from self.response()
cls = http.cls_for_code(self._response.status)
if issubclass(cls, self.expected):
return data
return (yield from self.upgraded_response())
else:
raise cls(self, data)
try:
data = yield from self.upgraded_response()
except Exception as exc:
raise cls(self, None) from exc
else:
raise cls(self, data)

__iter__ = __await__ # compatibility with yield from (i.e. in __await__)

Expand Down
47 changes: 46 additions & 1 deletion napper/tests/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .util import Tests
from .. import CrossOriginRequestError
from ..request import Request, SessionFactory
from ..response import PermalinkString
from ..response import PermalinkString, ResponseType
from .. import util, restspec, errors


Expand Down Expand Up @@ -291,3 +291,48 @@ def test_close_session(self):
with session:
self.assertFalse(ah_session.closed)
self.assertTrue(ah_session.closed)


class ResponseTypeTests(Tests):
def setUp(self):
super().setUp()

class CustomException(Exception):
pass

class ErrorOnParse(ResponseType):
async def parse_response(self, response):
raise CustomException

self.CustomException = CustomException
self.ErrorOnParse = ErrorOnParse

async def test_parse_exc(self):
req = self.site.path.get()
req.response_type = self.ErrorOnParse()
with self.text_response('{}'):
with self.assertRaises(self.CustomException):
await req

async def test_unexpected_status_and_parse_exc(self):
req = self.site.path.get()
req.response_type = self.ErrorOnParse()
with self.text_response('{}', status=400):
with self.assertRaises(errors.http.BadRequest) as r:
await req
with self.assertRaises(self.CustomException):
r.exception.response

async def test_unexpected_status_and_prepare_exc_await_twice(self):
req = self.site.path.get()
req.response_type = self.ErrorOnParse()
with self.text_response('{}', status=400):
with self.assertRaises(errors.http.BadRequest) as r:
await req
with self.assertRaises(self.CustomException):
r.exception.response

with self.assertRaises(errors.http.BadRequest) as r:
await req
with self.assertRaises(self.CustomException):
r.exception.response

0 comments on commit f772f25

Please sign in to comment.