In the case where there are command groups and every sub-command may raise exceptions, how can I handle them all together in one place?
Given the example below:
import click
@click.group()
def cli():
    pass
@cli.command()
def foo():
    pass
if __name__ == '__main__':
    cli()
Both cli and foo may raise. I know that one possible solution is to place try-except around cli() in the if clause. But that does not work when you distribute a package. In setup.py, you have to specify an entry point (in this case, cli). The if clause will not be executed.
You can create a custom click.Group by inheriting from same.  The custom group can be used by passing it as the cls parameter to the click.group() decorator.  If you override the __call__ method, you can insert an exception handler like:
class CatchAllExceptions(click.Group):
    def __call__(self, *args, **kwargs):
        try:
            return self.main(*args, **kwargs)
        except Exception as exc:
            click.echo('We found %s' % exc)
import click
@click.group(cls=CatchAllExceptions)
def cli():
    pass
@cli.command()
def foo():
    raise Exception('an exception!')
if __name__ == '__main__':
    cli('foo'.split())
We found an exception!
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With