From 016197c16eb64edfd9c19a8fabc9e2318a12cb78 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 12 Sep 2016 15:49:54 -0700 Subject: [PATCH] Catch APIError while printing container logs Signed-off-by: Joffrey F --- compose/cli/log_printer.py | 11 +++++++++-- tests/unit/cli/log_printer_test.py | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/compose/cli/log_printer.py b/compose/cli/log_printer.py index b48462ff5..299ddea46 100644 --- a/compose/cli/log_printer.py +++ b/compose/cli/log_printer.py @@ -6,6 +6,7 @@ from collections import namedtuple from itertools import cycle from threading import Thread +from docker.errors import APIError from six.moves import _thread as thread from six.moves.queue import Empty from six.moves.queue import Queue @@ -176,8 +177,14 @@ def build_log_generator(container, log_args): def wait_on_exit(container): - exit_code = container.wait() - return "%s exited with code %s\n" % (container.name, exit_code) + try: + exit_code = container.wait() + return "%s exited with code %s\n" % (container.name, exit_code) + except APIError as e: + return "Unexpected API error for %s (HTTP code %s)\nResponse body:\n%s\n" % ( + container.name, e.response.status_code, + e.response.text or '[empty]' + ) def start_producer_thread(thread_args): diff --git a/tests/unit/cli/log_printer_test.py b/tests/unit/cli/log_printer_test.py index ab48eefc0..b908eb68b 100644 --- a/tests/unit/cli/log_printer_test.py +++ b/tests/unit/cli/log_printer_test.py @@ -4,7 +4,9 @@ from __future__ import unicode_literals import itertools import pytest +import requests import six +from docker.errors import APIError from six.moves.queue import Queue from compose.cli.log_printer import build_log_generator @@ -56,6 +58,26 @@ def test_wait_on_exit(): assert expected == wait_on_exit(mock_container) +def test_wait_on_exit_raises(): + status_code = 500 + + def mock_wait(): + resp = requests.Response() + resp.status_code = status_code + raise APIError('Bad server', resp) + + mock_container = mock.Mock( + spec=Container, + name='cname', + wait=mock_wait + ) + + expected = 'Unexpected API error for {} (HTTP code {})\n'.format( + mock_container.name, status_code, + ) + assert expected in wait_on_exit(mock_container) + + def test_build_no_log_generator(mock_container): mock_container.has_api_logs = False mock_container.log_driver = 'none'