浏览代码

Add specific handling for pywintypes.error

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 8 年之前
父节点
当前提交
d2cbf33412
共有 2 个文件被更改,包括 41 次插入0 次删除
  1. 20 0
      compose/cli/errors.py
  2. 21 0
      tests/unit/cli/errors_test.py

+ 20 - 0
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):

+ 21 - 0
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]