def on_post(self, req, resp, service): try: svc = self.service_instances[service] except KeyError: self.log.error("Unknown service '%s'", service) raise falcon.HTTPNotFound() if req.content_type and "application/json" not in req.content_type: self.log.error("Unsupported request content type '%s'", req.content_type) raise falcon.HTTPUnsupportedMediaType() try: body = req.bounded_stream.read() headers = req.headers svc_req = Request.from_http(body, headers) except Exception as exc: self.log.error( "Bad request (body: %s, headers: %s): %s", body, headers, exc ) exc = errors.BadRequest(str(exc)) resp.status = exc.http_response_code resp.data = json.dumps(exc.as_dict()).encode("utf-8") self.log.debug("Response body: %s", resp.data) else: svc_resp = svc._execute(svc_req) resp.status = svc_resp.http_status resp.data = svc_resp.http_body for k, v in svc_resp.http_headers.items(): resp.append_header(k, v)
def raise_service(context, exc_name, *exc_args): context.log.info("raise(%s, %s): Entering", exc_name, exc_args) if exc_name == "CustomError": exc = CustomError(*exc_args) elif exc_name == "IOError": try: open(exc_args[0]) except IOError as io_exc: exc = io_exc elif exc_name == "BadRequest": exc = errors.BadRequest(*exc_args) elif exc_name == "RetryLater": exc = errors.RetryLater(*exc_args) else: try: exc_class = __builtins__[exc_name] except KeyError: context.log.exception("Unknown exception class '%s'", exc_name) raise Exception("<%s(%s)>" % (exc_name, exc_args)) try: exc = exc_class(*exc_args) except Exception: context.log.exception("Cannot instantiate %s(%s)", exc_name, exc_args) exc = Exception("<%s(%s)>" % (exc_name, exc_args)) context.log.info("Raising %s (type: %s)", exc, type(exc)) raise exc
data=json.dumps(["CustomError", "Oops!"])) exc = exc.value.exc_type assert exc == Exception try: raise Exception("Some error") except Exception: exc_type, exc_value, exc_tb = sys.exc_info() @pytest.mark.parametrize( "error", [ errors.BadRequest("foo"), errors.CommError("Can't hear you"), errors.RetryLater("Server too busy", 42), errors.ServiceError("Who knows"), errors.TaskError("some-service", exc_type, exc_value, exc_tb), errors.Timeout("I'm tired"), ], ) def test_serialize_roundtrip(error): ser = error.as_dict() err = errors.Serializable.from_dict(ser) assert err == error @pytest.mark.parametrize( "err, expected",
from __future__ import absolute_import, unicode_literals import pytest from servicelib import core, errors from servicelib.metadata import Metadata @pytest.mark.parametrize("tracker", [core.tracker() for _ in range(100)]) def test_tracker_format(tracker): assert core.is_valid_tracker(tracker) def test_invalid_tracker(): assert not core.is_valid_tracker("foo") assert not core.is_valid_tracker(None) assert not core.is_valid_tracker(42) def test_request_serialize_roundtrip(): req = core.Request(["foo", 42, 42.0], cache=False, tracker=core.tracker()) ser = core.Request.from_http(req.http_body, req.http_headers) assert ser == req @pytest.mark.parametrize("value", ["some-value", errors.BadRequest("Oops"),]) def test_response_serialize_roundtrip(value): res = core.Response(value, Metadata("some-service")) ser = core.Response.from_http(res.http_status, res.http_body, res.http_headers) assert ser == res
with pytest.raises(Exception) as exc: worker.http_post( "/services/hello", data="world, valid text/plain, but not supported", headers={"content-type": "text/plain"}, ) assert str(exc.value).startswith("415") @pytest.mark.parametrize( "req,expected", [ ( "This is not valid JSON", set([ errors.BadRequest("No JSON object could be decoded"), errors.BadRequest("Expecting value: line 1 column 1 (char 0)"), ]), ), ( json.dumps("Valid JSON, but list expected"), set([errors.BadRequest("List expected")]), ), ], ) def test_malformed_request(worker, req, expected): with pytest.raises(errors.BadRequest) as exc: worker.http_post("/services/hello", data=req) assert exc.value in expected