Skip to content

Commit

Permalink
service: detailed error messages for create and start
Browse files Browse the repository at this point in the history
Fixes: docker#3355

Signed-off-by: Tomas Tomecek <ttomecek@redhat.com>
  • Loading branch information
TomasTomecek authored and aanand committed Jul 27, 2016
1 parent f7853a3 commit e1b7510
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 4 deletions.
4 changes: 3 additions & 1 deletion compose/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from ..service import ConvergenceStrategy
from ..service import ImageType
from ..service import NeedsBuildError
from ..service import OperationFailedError
from .command import get_config_from_options
from .command import project_from_options
from .docopt_command import DocoptDispatcher
Expand Down Expand Up @@ -61,7 +62,8 @@ def main():
except (KeyboardInterrupt, signals.ShutdownException):
log.error("Aborting.")
sys.exit(1)
except (UserError, NoSuchService, ConfigurationError, ProjectError) as e:
except (UserError, NoSuchService, ConfigurationError,
ProjectError, OperationFailedError) as e:
log.error(e.msg)
sys.exit(1)
except BuildError as e:
Expand Down
7 changes: 7 additions & 0 deletions compose/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals


class OperationFailedError(Exception):
def __init__(self, reason):
self.msg = reason
4 changes: 4 additions & 0 deletions compose/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from six.moves.queue import Queue

from compose.cli.signals import ShutdownException
from compose.errors import OperationFailedError
from compose.utils import get_output_stream


Expand Down Expand Up @@ -47,6 +48,9 @@ def parallel_execute(objects, func, get_name, msg, get_deps=None):
elif isinstance(exception, APIError):
errors[get_name(obj)] = exception.explanation
writer.write(get_name(obj), 'error')
elif isinstance(exception, OperationFailedError):
errors[get_name(obj)] = exception.msg
writer.write(get_name(obj), 'error')
elif isinstance(exception, UpstreamError):
writer.write(get_name(obj), 'error')
else:
Expand Down
12 changes: 10 additions & 2 deletions compose/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .const import LABEL_SERVICE
from .const import LABEL_VERSION
from .container import Container
from .errors import OperationFailedError
from .parallel import parallel_execute
from .parallel import parallel_start
from .progress_stream import stream_output
Expand Down Expand Up @@ -277,7 +278,11 @@ def create_container(self,
if 'name' in container_options and not quiet:
log.info("Creating %s" % container_options['name'])

return Container.create(self.client, **container_options)
try:
return Container.create(self.client, **container_options)
except APIError as ex:
raise OperationFailedError("Cannot create container for service %s: %s" %
(self.name, ex.explanation))

def ensure_image_exists(self, do_build=BuildAction.none):
if self.can_be_built() and do_build == BuildAction.force:
Expand Down Expand Up @@ -447,7 +452,10 @@ def start_container_if_stopped(self, container, attach_logs=False, quiet=False):

def start_container(self, container):
self.connect_container_to_networks(container)
container.start()
try:
container.start()
except APIError as ex:
raise OperationFailedError("Cannot start service %s: %s" % (self.name, ex.explanation))
return container

def connect_container_to_networks(self, container):
Expand Down
5 changes: 4 additions & 1 deletion tests/integration/service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,10 @@ def test_scale_with_api_error(self):

self.assertEqual(len(service.containers()), 1)
self.assertTrue(service.containers()[0].is_running)
self.assertIn("ERROR: for composetest_web_2 Boom", mock_stderr.getvalue())
self.assertIn(
"ERROR: for composetest_web_2 Cannot create container for service web: Boom",
mock_stderr.getvalue()
)

def test_scale_with_unexpected_exception(self):
"""Test that when scaling if the API returns an error, that is not of type
Expand Down

0 comments on commit e1b7510

Please sign in to comment.