#!/usr/bin/env python # coding: utf-8 # # Tutorial 4: Error handling # This tutorial explains how errors are reported by the zhmcclient package to its users, and how they can be handled. # Error handling in the zhmcclient package is based on Python exceptions. # # If you have not dealt with Python exceptions yet, here are a few good articles about them: # # * [Jeff Knupp: Write Cleaner Python: Use Exceptions](https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/) # * [Eli Bendersky: Robust exception handling](http://eli.thegreenplace.net/2008/08/21/robust-exception-handling/) # * [Ian Bicking: Re-raising Exceptions](http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html) # * [Sheena: Writing and Using Custom Exceptions in Python](https://www.codementor.io/python/tutorial/how-to-write-python-custom-exceptions) # * [Joel Spolsky: Exceptions](http://www.joelonsoftware.com/items/2003/10/13.html) (a critical view on exceptions) # # The zhmcclient package raises two kinds of exceptions: # # * Exceptions derived from [`zhmcclient.Error`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.Error). Such exceptions indicate for example errors in the communication with the HMC, or authentication errors, or the HMC was unable to find a particular resource by name. # # * Other exceptions. Other exceptions should not normally be raised, and most of the time indicate a programming error, either on behalf of the zhmcclient package, or on behalf of the user using it. # # The documentation of the zhmcclient API lists for the most part only the exceptions derived from `zhmcclient.Error`. Other exceptions may in addition be raised and should be considered programming errors. # The following list shows the class hierarchy of `zhmcclient.Error` exceptions and its derived exceptions: # # * [`zhmcclient.Error`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.Error) - exception base class. It is an abstract base class, meaning that this exception is not raised; but it is the base class for all zhmcclient-defined exception classes and can therefore be used to catch all zhmcclient-specific exceptions: # * [`zhmcclient.ConnectionError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ConnectionError) - indicates a problem with the connection to the HMC, at the transport level or below. Is used both for being raised, and as a base class for more specific exceptions: # * [`zhmcclient.ConnectTimeout`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ConnectTimeout) - indicates that a connection to the HMC timed out after exhausting the connect retries. # * [`zhmcclient.RetriesExceeded`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.RetriesExceeded) - indicates that the maximum number of retries for connecting to the HMC, sending HTTP requests or reading HTTP responses was exceeded, for reasons other than connect timeouts. # * [`zhmcclient.ReadTimeout`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ConnectTimeout) - indicates that reading an HTTP response from the HMC timed out after exhausting the read retries. # * [`zhmcclient.AuthError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.AuthError) - indicates an authentication error with the HMC, either at the TLS/SSL handshake level (e.g. with CA certificates), or at the HTTP level. Is used both for being raised, and as a base class for more specific exceptions: # * [`zhmcclient.ClientAuthError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ClientAuthError) - indicates an authentication related problem detected on the client side. # * [`zhmcclient.ServerAuthError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ServerAuthError) - indicates an authentication error with the HMC. # * [`zhmcclient.HTTPError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.HTTPError) - indicates that the HMC returned an HTTP response with a bad HTTP status code. # * [`zhmcclient.OperationTimeout`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.OperationTimeout) - indicates that the waiting for completion of an asynchronous HMC operation has timed out. # * [`zhmcclient.StatusTimeout`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.StatusTimeout) - indicates that the waiting for reaching a desired LPAR or Partition status has timed out. # * [`zhmcclient.ParseError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ParseError) - indicates a parsing error while processing a response from the HMC. # * [`zhmcclient.VersionError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.VersionError) - indicates that there is a version mismatch between the HMC API versions supported by the client and by the HMC. # * [`zhmcclient.NoUniqueMatch`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.NoUniqueMatch) - indicates that more than one resource matched the filter arguments. # * [`zhmcclient.NotFound`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.NotFound) - indicates that a resource was not found based on the filter arguments. # The following code can be used to play around and see how some exceptions are triggered: # # * `zhmcclient.ConnectionError`, if you specify an IP address in the `zhmc` variable that cannot be reached from where you run this Jupyter notebook. # * `zhmcclient.AuthError`, if you specify an HMC userid that does not exist or if the password is invalid (assuming the IP address can be reached). # * `zhmcclient.HTTPError`, if the password is the empty string. # * Python `RuntimeError`, if you run this on a Python version that is not supported for the zhmcclient package (this may be a stupid example, but it is an example of a non-zhmcclient exception and indicates a user error). # In[ ]: import tututils import zhmcclient zhmc = '9.152.150.65' # edit this to your HMC's IP address or host name user = 'ensadmin' # edit this to the userid on that HMC client = tututils.make_client(zhmc, user) # The basic approach for handling exceptions with the zhmcclient package is the following: # * Handle all exceptions derived from `zhmcclient.Error`. # * Ignore all other exceptions (or let them be handled like you would handle programming errors). # There are also situations where you want to handle specific zhmcclient exceptions in order to react to the situation. The following example code uses a backup CPC is the primary CPC cannot be found: # In[ ]: primary_cpc_name = 'CPC1' backup_cpc_name = 'CPC1B' try: cpc = client.cpcs.find(name=primary_cpc_name) except zhmcclient.NotFound: cpc = client.cpcs.find(name=backup_cpc_name) print("Using CPC {}".format(cpc.name))