summaryrefslogtreecommitdiff
path: root/doc/source/command-errors.rst
diff options
context:
space:
mode:
authorDoug Hellmann <doug@doughellmann.com>2017-06-13 15:55:33 -0400
committerAndreas Jaeger <aj@suse.com>2017-06-23 11:54:32 +0200
commit9599ffe65d9dcd4b3aa780d346eccd1e760890bf (patch)
tree9281e521e50b8bed66eca087bc11fa03adf2aed3 /doc/source/command-errors.rst
parent19c8cabeca1ea3c83da734ab5269318b27eb5634 (diff)
downloadpython-openstackclient-9599ffe65d9dcd4b3aa780d346eccd1e760890bf.tar.gz
reorganize existing documentation according to the new standard layout
Move existing content around based on the doc-migration specification. Replace :doc: markup with :ref: to have sphinx keep track of where the files move and generate valid hyperlinks. Add a few toctrees and index pages for the new directories. Depends-On: Ia750cb049c0f53a234ea70ce1f2bbbb7a2aa9454 Change-Id: I253ee8f89d3ec40e39310c18bb87ed1d3d5de330 Signed-off-by: Doug Hellmann <doug@doughellmann.com>
Diffstat (limited to 'doc/source/command-errors.rst')
-rw-r--r--doc/source/command-errors.rst202
1 files changed, 0 insertions, 202 deletions
diff --git a/doc/source/command-errors.rst b/doc/source/command-errors.rst
deleted file mode 100644
index c4adb7d1..00000000
--- a/doc/source/command-errors.rst
+++ /dev/null
@@ -1,202 +0,0 @@
-==============
-Command Errors
-==============
-
-Handling errors in OpenStackClient commands is fairly straightforward. An
-exception is thrown and handled by the application-level caller.
-
-Note: There are many cases that need to be filled out here. The initial
-version of this document considers the general command error handling as well
-as the specific case of commands that make multiple REST API calls and how to
-handle when one or more of those calls fails.
-
-General Command Errors
-======================
-
-The general pattern for handling OpenStackClient command-level errors is to
-raise a CommandError exception with an appropriate message. This should include
-conditions arising from arguments that are not valid/allowed (that are not otherwise
-enforced by ``argparse``) as well as errors arising from external conditions.
-
-External Errors
----------------
-
-External errors are a result of things outside OpenStackClient not being as
-expected.
-
-Example
-~~~~~~~
-
-This example is taken from ``keypair create`` where the ``--public-key`` option
-specifies a file containing the public key to upload. If the file is not found,
-the IOError exception is trapped and a more specific CommandError exception is
-raised that includes the name of the file that was attempted to be opened.
-
-.. code-block:: python
-
- class CreateKeypair(command.ShowOne):
- """Create new public key"""
-
- ## ...
-
- def take_action(self, parsed_args):
- compute_client = self.app.client_manager.compute
-
- public_key = parsed_args.public_key
- if public_key:
- try:
- with io.open(
- os.path.expanduser(parsed_args.public_key),
- "rb"
- ) as p:
- public_key = p.read()
- except IOError as e:
- msg = _("Key file %s not found: %s")
- raise exceptions.CommandError(
- msg % (parsed_args.public_key, e),
- )
-
- keypair = compute_client.keypairs.create(
- parsed_args.name,
- public_key=public_key,
- )
-
- ## ...
-
-REST API Errors
-===============
-
-Most commands make a single REST API call via the supporting client library
-or SDK. Errors based on HTML return codes are usually handled well by default,
-but in some cases more specific or user-friendly messages need to be logged.
-Trapping the exception and raising a CommandError exception with a useful
-message is the correct approach.
-
-Multiple REST API Calls
------------------------
-
-Some CLI commands make multiple calls to library APIs and thus REST APIs.
-Most of the time these are ``create`` or ``set`` commands that expect to add or
-change a resource on the server. When one of these calls fails, the behaviour
-of the remainder of the command handler is defined as such:
-
-* Whenever possible, all API calls will be made. This may not be possible for
- specific commands where the subsequent calls are dependent on the results of
- an earlier call.
-
-* Any failure of an API call will be logged for the user
-
-* A failure of any API call results in a non-zero exit code
-
-* In the cases of failures in a ``create`` command a follow-up mode needs to
- be present that allows the user to attempt to complete the call, or cleanly
- remove the partially-created resource and re-try.
-
-The desired behaviour is for commands to appear to the user as idempotent
-whenever possible, i.e. a partial failure in a ``set`` command can be safely
-retried without harm. ``create`` commands are a harder problem and may need
-to be handled by having the proper options in a set command available to allow
-recovery in the case where the primary resource has been created but the
-subsequent calls did not complete.
-
-Example 1
-~~~~~~~~~
-
-This example is taken from the ``volume snapshot set`` command where ``--property``
-arguments are set using the volume manager's ``set_metadata()`` method,
-``--state`` arguments are set using the ``reset_state()`` method, and the
-remaining arguments are set using the ``update()`` method.
-
-.. code-block:: python
-
- class SetSnapshot(command.Command):
- """Set snapshot properties"""
-
- ## ...
-
- def take_action(self, parsed_args):
- volume_client = self.app.client_manager.volume
- snapshot = utils.find_resource(
- volume_client.volume_snapshots,
- parsed_args.snapshot,
- )
-
- kwargs = {}
- if parsed_args.name:
- kwargs['name'] = parsed_args.name
- if parsed_args.description:
- kwargs['description'] = parsed_args.description
-
- result = 0
- if parsed_args.property:
- try:
- volume_client.volume_snapshots.set_metadata(
- snapshot.id,
- parsed_args.property,
- )
- except SomeException: # Need to define the exceptions to catch here
- LOG.error(_("Property set failed"))
- result += 1
-
- if parsed_args.state:
- try:
- volume_client.volume_snapshots.reset_state(
- snapshot.id,
- parsed_args.state,
- )
- except SomeException: # Need to define the exceptions to catch here
- LOG.error(_("State set failed"))
- result += 1
-
- try:
- volume_client.volume_snapshots.update(
- snapshot.id,
- **kwargs
- )
- except SomeException: # Need to define the exceptions to catch here
- LOG.error(_("Update failed"))
- result += 1
-
- # NOTE(dtroyer): We need to signal the error, and a non-zero return code,
- # without aborting prematurely
- if result > 0:
- raise SomeNonFatalException
-
-Example 2
-~~~~~~~~~
-
-This example is taken from the ``network delete`` command which takes multiple
-networks to delete. All networks will be deleted in a loop, which makes
-multiple ``delete_network()`` calls.
-
-.. code-block:: python
-
- class DeleteNetwork(common.NetworkAndComputeCommand):
- """Delete network(s)"""
-
- def update_parser_common(self, parser):
- parser.add_argument(
- 'network',
- metavar="<network>",
- nargs="+",
- help=_("Network(s) to delete (name or ID)")
- )
- return parser
-
- def take_action(self, client, parsed_args):
- ret = 0
-
- for network in parsed_args.network:
- try:
- obj = client.find_network(network, ignore_missing=False)
- client.delete_network(obj)
- except Exception:
- LOG.error(_("Failed to delete network with name "
- "or ID %s."), network)
- ret += 1
-
- if ret > 0:
- total = len(parsed_args.network)
- msg = (_("Failed to delete %(ret)s of %(total)s networks.")
- % {"ret": ret, "total": total})
- raise exceptions.CommandError(msg)