From ee87c4d64285b46f342ca3254c8c594932c89e78 Mon Sep 17 00:00:00 2001 From: Khushiyant Date: Wed, 19 Mar 2025 13:15:52 +0530 Subject: [PATCH 1/2] chore: handle error details in stream response --- docker/api/image.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/api/image.py b/docker/api/image.py index 85109473b..fdd9c1cc0 100644 --- a/docker/api/image.py +++ b/docker/api/image.py @@ -495,7 +495,11 @@ def push(self, repository, tag=None, stream=False, auth_config=None, self._raise_for_status(response) if stream: - return self._stream_helper(response, decode=decode) + for line in self._stream_helper(response, decode=decode): + if isinstance(line, dict) and "errorDetail" in line: + raise errors.APIError(line["errorDetail"]["message"]) + yield line + return self._result(response) From 00d1f3177d385e4c20afc59f039210d4127d4721 Mon Sep 17 00:00:00 2001 From: Khushiyant Date: Wed, 19 Mar 2025 18:53:30 +0530 Subject: [PATCH 2/2] chore: add test for stream error handling --- docker/api/image.py | 14 +++++++++----- tests/unit/api_image_test.py | 7 +++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docker/api/image.py b/docker/api/image.py index fdd9c1cc0..484a40736 100644 --- a/docker/api/image.py +++ b/docker/api/image.py @@ -1,5 +1,6 @@ import logging import os +from json import JSONDecodeError from .. import auth, errors, utils from ..constants import DEFAULT_DATA_CHUNK_SIZE @@ -495,11 +496,14 @@ def push(self, repository, tag=None, stream=False, auth_config=None, self._raise_for_status(response) if stream: - for line in self._stream_helper(response, decode=decode): - if isinstance(line, dict) and "errorDetail" in line: - raise errors.APIError(line["errorDetail"]["message"]) - yield line - + try: + for line in self._stream_helper(response, decode=decode): + if isinstance(line, dict) and "errorDetail" in line: + message = line["errorDetail"]["message"] + raise errors.APIError(message=message) + yield line + except JSONDecodeError as e: + raise JSONDecodeError("Error decoding response stream") from e return self._result(response) diff --git a/tests/unit/api_image_test.py b/tests/unit/api_image_test.py index 148109d37..4f2e2bdad 100644 --- a/tests/unit/api_image_test.py +++ b/tests/unit/api_image_test.py @@ -4,6 +4,7 @@ import docker from docker import auth +import docker.errors from . import fake_api from .api_test import ( @@ -288,6 +289,12 @@ def test_push_image_stream(self): timeout=DEFAULT_TIMEOUT_SECONDS ) + def test_push_image_with_exception(self): + with pytest.raises(Exception): + self.client.push("docker", stream=True, tag='tag', decode=True) + self.fail('An exception should have been raised') + + def test_tag_image(self): self.client.tag(fake_api.FAKE_IMAGE_ID, fake_api.FAKE_REPO_NAME)