diff --git a/solar/cli/base.py b/solar/cli/base.py index cec4f330..7277218e 100644 --- a/solar/cli/base.py +++ b/solar/cli/base.py @@ -12,8 +12,13 @@ # License for the specific language governing permissions and limitations # under the License. +from functools import wraps + import click +from solar.dblayer.model import DBLayerException +from solar.errors import SolarError + class AliasedGroup(click.Group): """This class introduces iproute2-like behaviour, @@ -40,13 +45,27 @@ class AliasedGroup(click.Group): ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) -class EGroup(click.Group): - +class BaseGroup(click.Group): error_wrapper_enabled = False - error_wrapper = None - def add_command(self, cmd, name=None): - if self.error_wrapper: - cmd.callback = self.error_wrapper(cmd.callback) - return super(EGroup, self).add_command(cmd, name) + cmd.callback = self.error_wrapper(cmd.callback) + return super(BaseGroup, self).add_command(cmd, name) + + def error_wrapper(self, f): + @wraps(f) + def _in(*args, **kwargs): + try: + return f(*args, **kwargs) + except (SolarError, DBLayerException) as e: + self.handle_exception(e) + if self.error_wrapper_enabled: + raise click.ClickException(str(e)) + raise + except Exception as e: + self.handle_exception(e) + raise + return _in + + def handle_exception(self, e): + pass diff --git a/solar/cli/events.py b/solar/cli/events.py index 8ebb2cd9..b585d737 100644 --- a/solar/cli/events.py +++ b/solar/cli/events.py @@ -17,10 +17,15 @@ import subprocess import click import networkx as nx +from solar.cli.base import BaseGroup from solar.events import api as evapi -@click.group() +class EventsGroup(BaseGroup): + pass + + +@click.group(cls=EventsGroup) def events(): pass diff --git a/solar/cli/inputs.py b/solar/cli/inputs.py index e7db3fc1..71a4aea8 100644 --- a/solar/cli/inputs.py +++ b/solar/cli/inputs.py @@ -15,11 +15,16 @@ import click import yaml +from solar.cli.base import BaseGroup from solar.core import resource as sresource from solar.dblayer.model import NONE -@click.group(help="Manages raw resource inputs") +class InputsGroup(BaseGroup): + pass + + +@click.group(help="Manages raw resource inputs", cls=InputsGroup) def inputs(): pass diff --git a/solar/cli/main.py b/solar/cli/main.py index a036d7df..8ac79e4f 100644 --- a/solar/cli/main.py +++ b/solar/cli/main.py @@ -63,7 +63,7 @@ def show_emitter_connections(res): def main(debug): debug = debug or os.getenv("SOLAR_CLI_DEBUG") if not debug: - base.EGroup.error_wrapper_enabled = True + base.BaseGroup.error_wrapper_enabled = True def init_actions(): diff --git a/solar/cli/orch.py b/solar/cli/orch.py index ccb49e5e..a493b2e4 100755 --- a/solar/cli/orch.py +++ b/solar/cli/orch.py @@ -18,6 +18,7 @@ import time import click +from solar.cli.base import BaseGroup from solar.cli.uids_history import remember_uid from solar.cli.uids_history import SOLARUID from solar.dblayer.locking import DBLock @@ -29,7 +30,11 @@ from solar.orchestration.traversal import states from solar.orchestration import utils -@click.group(name='orch') +class OrchGroup(BaseGroup): + pass + + +@click.group(name='orch', cls=OrchGroup) def orchestration(): pass @@ -58,7 +63,7 @@ def wait_report(uid, timeout, interval=3): except errors.SolarError: click.echo('') click_report(uid) - sys.exit(1) + raise else: click.echo('') click_report(uid) diff --git a/solar/cli/repository.py b/solar/cli/repository.py index c8952ac6..48312958 100644 --- a/solar/cli/repository.py +++ b/solar/cli/repository.py @@ -13,32 +13,17 @@ # under the License. import click -from functools import wraps import os import yaml +from solar.cli.base import BaseGroup from solar.core.resource.repository import Repository -from solar.core.resource.repository import RepositoryException - -from solar.cli.base import EGroup -class RepoGroup(EGroup): - - def error_wrapper(self, f): - @wraps(f) - def _in(*args, **kwargs): - try: - return f(*args, **kwargs) - except OSError as e: - if self.error_wrapper_enabled: - raise click.ClickException(str(e)) - raise - except RepositoryException as e: - if self.error_wrapper_enabled: - raise click.ClickException(str(e)) - raise - return _in +class RepoGroup(BaseGroup): + def handle_exception(self, e): + if e is OSError: + raise click.ClickException(str(e)) @click.group(help="Manages Solar repositories", cls=RepoGroup) diff --git a/solar/cli/resource.py b/solar/cli/resource.py index 4d49ba2d..a406c40e 100644 --- a/solar/cli/resource.py +++ b/solar/cli/resource.py @@ -16,29 +16,17 @@ import json import os import click -from functools import wraps import yaml -from solar.cli.base import EGroup +from solar.cli.base import BaseGroup from solar.cli import executors from solar.core import actions from solar.core import resource as sresource from solar.core.resource import composer as cr -from solar import errors -class ResourceGroup(EGroup): - - def error_wrapper(self, f): - @wraps(f) - def _in(*args, **kwargs): - try: - return f(*args, **kwargs) - except errors.SolarError as e: - if self.error_wrapper_enabled: - raise click.ClickException(str(e)) - raise - return _in +class ResourceGroup(BaseGroup): + pass @click.group(cls=ResourceGroup) diff --git a/solar/cli/system_log.py b/solar/cli/system_log.py index dc059656..27764199 100644 --- a/solar/cli/system_log.py +++ b/solar/cli/system_log.py @@ -16,6 +16,7 @@ import sys import click +from solar.cli.base import BaseGroup from solar.cli.uids_history import remember_uid from solar.core import resource from solar.core import testing @@ -24,7 +25,11 @@ from solar.system_log import change from solar.system_log import data -@click.group() +class SystemLogGroup(BaseGroup): + pass + + +@click.group(cls=SystemLogGroup) def changes(): pass diff --git a/solar/core/resource/repository.py b/solar/core/resource/repository.py index 5d4c514e..3a68dd08 100644 --- a/solar/core/resource/repository.py +++ b/solar/core/resource/repository.py @@ -23,13 +23,14 @@ import semantic_version import shutil import yaml +from solar import errors from solar import utils RES_TYPE = Enum("Resource Types", 'Normal Composer') -class RepositoryException(Exception): +class RepositoryException(errors.SolarError): pass diff --git a/solar/dblayer/model.py b/solar/dblayer/model.py index a6807c34..98dac57f 100644 --- a/solar/dblayer/model.py +++ b/solar/dblayer/model.py @@ -33,7 +33,11 @@ class DBLayerException(Exception): class DBLayerNotFound(DBLayerException): - pass + def __init__(self, spec): + self.message = 'Object {} not found in db layer'.format(spec) + + def __str__(self): + return str(self.message) class DBLayerNoRiakObj(DBLayerException):