From d8194cf6f0c5fd5a08f1a0daa6b4022a5582d008 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 16 Oct 2017 12:41:29 -0700 Subject: [PATCH] Add specific handling for pywintypes.error Signed-off-by: Joffrey F --- compose/cli/errors.py | 20 ++++++++++++++++++++ tests/unit/cli/errors_test.py | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/compose/cli/errors.py b/compose/cli/errors.py index 23e065c99..1506aa660 100644 --- a/compose/cli/errors.py +++ b/compose/cli/errors.py @@ -57,6 +57,26 @@ def handle_connection_errors(client): except (ReadTimeout, socket.timeout) as e: log_timeout_error(client.timeout) raise ConnectionError() + except Exception as e: + if is_windows(): + import pywintypes + if isinstance(e, pywintypes.error): + log_windows_pipe_error(e) + raise ConnectionError() + raise + + +def log_windows_pipe_error(exc): + if exc.winerror == 232: # https://github.com/docker/compose/issues/5005 + log.error( + "The current Compose file version is not compatible with your engine version. " + "Please upgrade your Compose file to a more recent version, or set " + "a COMPOSE_API_VERSION in your environment." + ) + else: + log.error( + "Windows named pipe error: {} (code: {})".format(exc.strerror, exc.winerror) + ) def log_timeout_error(timeout): diff --git a/tests/unit/cli/errors_test.py b/tests/unit/cli/errors_test.py index 7406a8880..68326d1c7 100644 --- a/tests/unit/cli/errors_test.py +++ b/tests/unit/cli/errors_test.py @@ -7,6 +7,7 @@ from requests.exceptions import ConnectionError from compose.cli import errors from compose.cli.errors import handle_connection_errors +from compose.const import IS_WINDOWS_PLATFORM from tests import mock @@ -65,3 +66,23 @@ class TestHandleConnectionErrors(object): raise APIError(None, None, msg) mock_logging.error.assert_called_once_with(msg) + + @pytest.mark.skipif(not IS_WINDOWS_PLATFORM, reason='Needs pywin32') + def test_windows_pipe_error_no_data(self, mock_logging): + import pywintypes + with pytest.raises(errors.ConnectionError): + with handle_connection_errors(mock.Mock(api_version='1.22')): + raise pywintypes.error(232, 'WriteFile', 'The pipe is being closed.') + + _, args, _ = mock_logging.error.mock_calls[0] + assert "The current Compose file version is not compatible with your engine version." in args[0] + + @pytest.mark.skipif(not IS_WINDOWS_PLATFORM, reason='Needs pywin32') + def test_windows_pipe_error_misc(self, mock_logging): + import pywintypes + with pytest.raises(errors.ConnectionError): + with handle_connection_errors(mock.Mock(api_version='1.22')): + raise pywintypes.error(231, 'WriteFile', 'The pipe is busy.') + + _, args, _ = mock_logging.error.mock_calls[0] + assert "Windows named pipe error: The pipe is busy. (code: 231)" == args[0]