Skip to content

Commit

Permalink
Catch an aiohttp HttpProcessingError and instead raise an asyncprawco…
Browse files Browse the repository at this point in the history
…re ServerError.

Co-authored-by: Rolf Campbell <campbell.rolf@gmail.com>

(cherry picked from commit praw-dev/praw@d1280b1)
  • Loading branch information
endlisnis authored and LilSpazJoekp committed Jun 8, 2022
1 parent dea0af7 commit 0b4fcef
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Expand Up @@ -86,4 +86,5 @@ Source Contributors
- cmays90 `@cmays90 <https://github.com/cmays90>`_
- Dio Brando `@isFakeAccount <https://github.com/isFakeAccount>`_
- Josh Kim `@jsk56143 <https://github.com/jsk56143>`_
- Rolf Campbell `@endlisnis <https://github.com/endlisnis>`_
- Add "Name <email (optional)> and github profile link" above this line.
20 changes: 14 additions & 6 deletions asyncpraw/models/reddit/subreddit.py
Expand Up @@ -24,8 +24,10 @@
from xml.etree.ElementTree import XML

from aiohttp import ClientResponse
from aiohttp.http_exceptions import HttpProcessingError
from aiohttp.web_ws import WebSocketError
from asyncprawcore import Redirect
from asyncprawcore.exceptions import ServerError

from ...const import API_PATH, JPEG_HEADER
from ...exceptions import (
Expand Down Expand Up @@ -692,6 +694,13 @@ async def _submit_media(self, data: dict, timeout: int, websocket_url: str = Non
url = ws_update["payload"]["redirect"]
return await self._reddit.submission(url=url)

async def _read_and_post_media(self, media_path, upload_url, upload_data):
with open(media_path, "rb") as media:
response = await self._reddit._core._requestor._http.post(
upload_url, data=upload_data, files={"file": media}
)
return response

async def _upload_media(
self,
media_path: str,
Expand Down Expand Up @@ -744,14 +753,13 @@ async def _upload_media(
upload_url = f"https:{upload_lease['action']}"
upload_data = {item["name"]: item["value"] for item in upload_lease["fields"]}

with open(media_path, "rb") as media:
upload_data["file"] = media
response = await self._reddit._core._requestor._http.post(
upload_url, data=upload_data
)
response = await self._read_and_post_media(media_path, upload_url, upload_data)
if not response.status == 201:
self._parse_xml_response(response)
response.raise_for_status()
try:
response.raise_for_status()
except HttpProcessingError:
raise ServerError(response=response)

websocket_url = upload_response["asset"]["websocket_url"]

Expand Down
25 changes: 24 additions & 1 deletion tests/unit/models/reddit/test_subreddit.py
Expand Up @@ -71,13 +71,36 @@ async def test_invalid_media(self, connection_mock, _mock_upload_media, _mock_po
context_manager.__aenter__.return_value = recv_mock
connection_mock.return_value = context_manager

# websockets_mock().__aenter__.recv =
with pytest.raises(MediaPostFailed):
await Subreddit(self.reddit, display_name="test").submit_image(
"Test", "dummy path"
)
await self.reddit._core._requestor._http.close()

@mock.patch("asyncpraw.models.Subreddit._read_and_post_media")
@mock.patch(
"asyncpraw.Reddit.post",
return_value={
"json": {"data": {"websocket_url": ""}},
"args": {"action": "", "fields": []},
},
)
@mock.patch("aiohttp.client.ClientSession.ws_connect")
async def test_media_upload_500(self, connection_mock, _mock_post, mock_method):
from aiohttp.http_exceptions import HttpProcessingError
from asyncprawcore.exceptions import ServerError

response = mock.Mock()
response.status = 201
response.raise_for_status = mock.Mock(
side_effect=HttpProcessingError(code=500, message="")
)
mock_method.return_value = response
with pytest.raises(ServerError):
await Subreddit(self.reddit, display_name="test").submit_image(
"Test", "/dev/null"
)

def test_repr(self):
subreddit = Subreddit(self.reddit, display_name="name")
assert repr(subreddit) == "Subreddit(display_name='name')"
Expand Down

0 comments on commit 0b4fcef

Please sign in to comment.