{"action":"created","issue":{"url":"https://api.github.com/repos/ZeroCater/zc_common/issues/111","repository_url":"https://api.github.com/repos/ZeroCater/zc_common","labels_url":"https://api.github.com/repos/ZeroCater/zc_common/issues/111/labels{/name}","comments_url":"https://api.github.com/repos/ZeroCater/zc_common/issues/111/comments","events_url":"https://api.github.com/repos/ZeroCater/zc_common/issues/111/events","html_url":"https://github.com/ZeroCater/zc_common/pull/111","id":319066167,"number":111,"title":"Improve error message when unexpected request.data encountered during parsing","user":{"login":"amberylx","id":2628477,"avatar_url":"https://avatars1.githubusercontent.com/u/2628477?v=4","gravatar_id":"","url":"https://api.github.com/users/amberylx","html_url":"https://github.com/amberylx","followers_url":"https://api.github.com/users/amberylx/followers","following_url":"https://api.github.com/users/amberylx/following{/other_user}","gists_url":"https://api.github.com/users/amberylx/gists{/gist_id}","starred_url":"https://api.github.com/users/amberylx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amberylx/subscriptions","organizations_url":"https://api.github.com/users/amberylx/orgs","repos_url":"https://api.github.com/users/amberylx/repos","events_url":"https://api.github.com/users/amberylx/events{/privacy}","received_events_url":"https://api.github.com/users/amberylx/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-04-30T23:10:45Z","updated_at":"2018-05-01T00:06:53Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/ZeroCater/zc_common/pulls/111","html_url":"https://github.com/ZeroCater/zc_common/pull/111","diff_url":"https://github.com/ZeroCater/zc_common/pull/111.diff","patch_url":"https://github.com/ZeroCater/zc_common/pull/111.patch"},"body":"Ran into a scenario when sending a `POST` request to the gateway from a client-side javascript application, where `request.body` was of type `string` instead of type `object`. This unexpected data type is accepted initially, but is not handled or caught at any point in the request cycle, the result being that the final `request` that is passed to the backend Django view has an empty `request.POST` body.\r\n\r\nWalkthrough of request cycle:\r\n1. The client-side javascript application makes a request to `gateway` using the `requests` library, and passes an `options` object with `{body: <JSON API Resource Identifier Object>}`\r\n1. When the request hits `gateway` here: https://github.com/ZeroCater/gateway/blob/master/src/handleRoute.js#L30, `this.request.body` is of type `string` (but the code \"expects\" an `object`)\r\n1. `gateway` creates an event to be passed into the message bus here: https://github.com/ZeroCater/gateway/blob/master/src/handleRoute.js#L52 with kwargs where `body` is of type `string\r\n1. The created event is picked up by `microservice_events_listener.py`\r\n1. `microservice_events_listener.py` routes the request to the appropriate job task in `microservice_events.py`\r\n1. `microservice_events.py` calls `event_client.handle_request_event()`\r\n1. Which calls `create_django_request()` here: https://github.com/ZeroCater/zc_events/blob/master/zc_events/client.py#L352\r\n1. Which attaches the `string` body to `request.raw_body` here: https://github.com/ZeroCater/zc_events/blob/master/zc_events/django_request.py#L45\r\n1. Then the job task picks up the `request` object and parses the information in it via `zc_common.remote_resource.parsers` here: https://github.com/ZeroCater/zc_common/blob/master/zc_common/remote_resource/parsers.py#L62\r\n1. The conditional checking for `raw_body` here https://github.com/ZeroCater/zc_common/blob/master/zc_common/remote_resource/parsers.py#L63 is `True`, so `result` is set to the `string` body\r\n1. Then since we are expecting a body of type `Object` we do `result.get('data')` here: https://github.com/ZeroCater/zc_common/blob/master/zc_common/remote_resource/parsers.py#L72, but it raises an `AttributeError`since `result` is actually a string\r\n1. This error gets absorbed somewhere, I think here: https://github.com/encode/django-rest-framework/blob/master/rest_framework/request.py#L349\r\n1. Ultimately, `request.data` is set to an empty dictionary.\r\n\r\nEssentially, data goes in on one end, then gets silently swallowed and discarded somewhere deep down along a long request cycle chain.\r\n\r\nThis PR detects the discrepancy in data type, and raises and appropriate error with explanatory message."},"comment":{"url":"https://api.github.com/repos/ZeroCater/zc_common/issues/comments/385564673","html_url":"https://github.com/ZeroCater/zc_common/pull/111#issuecomment-385564673","issue_url":"https://api.github.com/repos/ZeroCater/zc_common/issues/111","id":385564673,"user":{"login":"amberylx","id":2628477,"avatar_url":"https://avatars1.githubusercontent.com/u/2628477?v=4","gravatar_id":"","url":"https://api.github.com/users/amberylx","html_url":"https://github.com/amberylx","followers_url":"https://api.github.com/users/amberylx/followers","following_url":"https://api.github.com/users/amberylx/following{/other_user}","gists_url":"https://api.github.com/users/amberylx/gists{/gist_id}","starred_url":"https://api.github.com/users/amberylx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amberylx/subscriptions","organizations_url":"https://api.github.com/users/amberylx/orgs","repos_url":"https://api.github.com/users/amberylx/repos","events_url":"https://api.github.com/users/amberylx/events{/privacy}","received_events_url":"https://api.github.com/users/amberylx/received_events","type":"User","site_admin":false},"created_at":"2018-05-01T00:06:53Z","updated_at":"2018-05-01T00:06:53Z","author_association":"CONTRIBUTOR","body":"Note: This PR is not strictly required for functionality in https://trello.com/c/xACK2j2O/1181-fetch-company-stats-by-page, but was uncovered during implementation."}}
{"actor":{"display_login":"amberylx"}}