Skip to content

Commit

Permalink
Watermark exception (#3019)
Browse files Browse the repository at this point in the history
Co-authored-by: Krystle Salazar <github@krysal.co>
Co-authored-by: Olga Bulat <obulat@gmail.com>
  • Loading branch information
3 people authored Nov 3, 2023
1 parent 374a93e commit b2a3970
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
19 changes: 17 additions & 2 deletions api/api/utils/watermark.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from textwrap import wrap

from django.conf import settings
from rest_framework import status
from rest_framework.exceptions import APIException

import requests
from PIL import Image, ImageDraw, ImageFont
from PIL import Image, ImageDraw, ImageFont, UnidentifiedImageError
from sentry_sdk import capture_exception


Expand All @@ -25,6 +27,14 @@
}


class UpstreamWatermarkException(APIException):
status_code = status.HTTP_424_FAILED_DEPENDENCY
default_detail = (
"Could not render watermarked image due to upstream provider error."
)
default_code = "upstream_watermark_failure"


class Dimension(Flag):
"""This enum represents the two dimensions of an image."""

Expand Down Expand Up @@ -169,12 +179,17 @@ def _open_image(url):
logger = parent_logger.getChild("_open_image")
try:
response = requests.get(url, headers=HEADERS)
response.raise_for_status()
img_bytes = BytesIO(response.content)
img = Image.open(img_bytes)
except requests.exceptions.RequestException as e:
capture_exception(e)
logger.error(f"Error requesting image: {e}")
raise UpstreamWatermarkException(f"{e}")
except UnidentifiedImageError as e:
capture_exception(e)
logger.error(f"Error loading image data: {e}")
return None, None
raise UpstreamWatermarkException(f"{e}")

return img, img.getexif()

Expand Down
29 changes: 29 additions & 0 deletions api/test/unit/views/test_image_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.http import HttpResponse

import pytest
from PIL import UnidentifiedImageError
from requests import Request, Response

from api.views.image_views import ImageViewSet
Expand Down Expand Up @@ -79,3 +80,31 @@ def test_thumbnail_uses_upstream_thumb_for_smk(
thumb_call.return_value = mock_response
api_client.get(f"/v1/images/{image.identifier}/thumb/")
thumb_call.assert_called_once_with(ANY, image, expected_thumb_url)


@pytest.mark.django_db
def test_watermark_raises_424_for_invalid_image(api_client):
image = ImageFactory.create()
expected_error_message = (
"cannot identify image file <_io.BytesIO object at 0xffff86d8fec0>"
)

with patch("PIL.Image.open") as mock_open:
mock_open.side_effect = UnidentifiedImageError(expected_error_message)
res = api_client.get(f"/v1/images/{image.identifier}/watermark/")
assert res.status_code == 424
assert res.data["detail"] == expected_error_message


@pytest.mark.django_db
def test_watermark_raises_424_for_404_image(api_client):
image = ImageFactory.create()

with patch("requests.get") as mock_get:
mock_get.return_value = Response()
mock_get.return_value.status_code = 404
mock_get.return_value.url = image.url
mock_get.return_value.reason = "Not Found"
res = api_client.get(f"/v1/images/{image.identifier}/watermark/")
assert res.status_code == 424
assert res.data["detail"] == f"404 Client Error: Not Found for url: {image.url}"

0 comments on commit b2a3970

Please sign in to comment.