From 9bc8bb07cf16c8a9116b8029e63d1015d150cccb Mon Sep 17 00:00:00 2001 From: Guillaume Calmettes Date: Thu, 5 Jun 2025 14:59:28 +0200 Subject: [PATCH] [Bugfix] properly catch PIL-related errors for vision models when incorrect data urls are provided (#19202) Signed-off-by: Guillaume Calmettes --- tests/multimodal/test_utils.py | 13 +++++++++++++ vllm/multimodal/utils.py | 30 +++++++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/tests/multimodal/test_utils.py b/tests/multimodal/test_utils.py index e4debb47ce..c8a5448221 100644 --- a/tests/multimodal/test_utils.py +++ b/tests/multimodal/test_utils.py @@ -141,6 +141,19 @@ async def test_fetch_image_local_files(image_url: str): f"file://{temp_dir}/../{os.path.basename(image_url)}") +@pytest.mark.asyncio +async def test_fetch_image_error_conversion(): + connector = MediaConnector() + broken_img = "data:image/png;base64,aGVsbG9fdmxsbV9jb21tdW5pdHkK" + + # PIL.UnidentifiedImageError should be converted to ValueError + with pytest.raises(ValueError): + await connector.fetch_image_async(broken_img) + + with pytest.raises(ValueError): + connector.fetch_image(broken_img) + + @pytest.mark.asyncio @pytest.mark.parametrize("video_url", TEST_VIDEO_URLS) @pytest.mark.parametrize("num_frames", [-1, 32, 1800]) diff --git a/vllm/multimodal/utils.py b/vllm/multimodal/utils.py index 2b34cdf40b..11a25f8515 100644 --- a/vllm/multimodal/utils.py +++ b/vllm/multimodal/utils.py @@ -9,7 +9,7 @@ from urllib.parse import ParseResult, urlparse import numpy as np import numpy.typing as npt import torch -from PIL import Image +from PIL import Image, UnidentifiedImageError import vllm.envs as envs from vllm.connections import HTTPConnection, global_http_connection @@ -185,11 +185,15 @@ class MediaConnector: """ image_io = ImageMediaIO(image_mode=image_mode) - return self.load_from_url( - image_url, - image_io, - fetch_timeout=envs.VLLM_IMAGE_FETCH_TIMEOUT, - ) + try: + return self.load_from_url( + image_url, + image_io, + fetch_timeout=envs.VLLM_IMAGE_FETCH_TIMEOUT, + ) + except UnidentifiedImageError as e: + # convert to ValueError to be properly caught upstream + raise ValueError(str(e)) from e async def fetch_image_async( self, @@ -204,11 +208,15 @@ class MediaConnector: """ image_io = ImageMediaIO(image_mode=image_mode) - return await self.load_from_url_async( - image_url, - image_io, - fetch_timeout=envs.VLLM_IMAGE_FETCH_TIMEOUT, - ) + try: + return await self.load_from_url_async( + image_url, + image_io, + fetch_timeout=envs.VLLM_IMAGE_FETCH_TIMEOUT, + ) + except UnidentifiedImageError as e: + # convert to ValueError to be properly caught upstream + raise ValueError(str(e)) from e def fetch_video( self,