Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to handle exceptions automatically with Python Click?

Click's exception handling documentation mentions that certain kinds of exceptions such as Abort, EOFError and KeyboardInterrupt are automatically handled gracefully by the framework.

For the application I'm writing, there are a lot of points from which exceptions could be generated. Terminating the application is the right step, but printing the stack trace isn't. I could always manually do this:

@cli.command()
def somecommand:
  try:
    # ...
  except Exception as e:
    click.echo(e)

However, is there a way to have Click handle all exceptions automatically?

like image 942
user2064000 Avatar asked Aug 25 '17 06:08

user2064000


1 Answers

In our CLI, all commands are grouped under a single command group. This allowed us to implement some behavior that needed to be executed for each command. One part of that is the exception handling.

Our entry point looks something like this:

 @click.group()
 @click.pass_context
 def entry_point(ctx):
      ctx.obj = {"example": "This could be the configuration"}

We use it to run global code, e.g. configure the context, but you can also define an empty method that does nothing. Other commands can be added to this command group either by using the @entry_point.command() decorator or entry_point.add_command(cmd).

For the exception handling, we wrap the entry_point in another method that handles the exceptions:

 def safe_entry_point():
      try:
          entry_point()
      except Exception as e:
          click.echo(e)

In setup.py, we configure the entry point for the CLI and point it to the wrapper:

 entry_points={
    'console_scripts': [
        'cli = my.package:safe_entry_point'
    ]
}

The commands of the CLI can be executed through its command group: e.g. cli command.

There might be more elegant solutions out there, but this is how we solved it. While it introduces a command group as the highest-level element in your CLI, but it allows us do handle all exceptions in a single place without the need to duplicate our error handling in each and every command.

like image 178
jdno Avatar answered Sep 28 '22 04:09

jdno