{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial 4: Error handling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial explains how errors are reported by the zhmcclient package to its users, and how they can be handled." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Error handling in the zhmcclient package is based on Python exceptions.\n", "\n", "If you have not dealt with Python exceptions yet, here are a few good articles about them:\n", "\n", "* [Jeff Knupp: Write Cleaner Python: Use Exceptions](https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/)\n", "* [Eli Bendersky: Robust exception handling](http://eli.thegreenplace.net/2008/08/21/robust-exception-handling/)\n", "* [Ian Bicking: Re-raising Exceptions](http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html)\n", "* [Sheena: Writing and Using Custom Exceptions in Python](https://www.codementor.io/python/tutorial/how-to-write-python-custom-exceptions)\n", "* [Joel Spolsky: Exceptions](http://www.joelonsoftware.com/items/2003/10/13.html) (a critical view on exceptions)\n", "\n", "The zhmcclient package raises two kinds of exceptions:\n", "\n", "* 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.\n", "\n", "* 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.\n", "\n", "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following list shows the class hierarchy of `zhmcclient.Error` exceptions and its derived exceptions:\n", "\n", "* [`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:\n", " * [`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:\n", " * [`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.\n", " * [`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.\n", " * [`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.\n", " * [`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:\n", " * [`zhmcclient.ClientAuthError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ClientAuthError) - indicates an authentication related problem detected on the client side.\n", " * [`zhmcclient.ServerAuthError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ServerAuthError) - indicates an authentication error with the HMC.\n", " * [`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.\n", " * [`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.\n", " * [`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.\n", " * [`zhmcclient.ParseError`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.ParseError) - indicates a parsing error while processing a response from the HMC.\n", " * [`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.\n", " * [`zhmcclient.NoUniqueMatch`](https://python-zhmcclient.readthedocs.io/en/latest/general.html#zhmcclient.NoUniqueMatch) - indicates that more than one resource matched the filter arguments.\n", " * [`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. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following code can be used to play around and see how some exceptions are triggered:\n", "\n", "* `zhmcclient.ConnectionError`, if you specify an IP address in the `zhmc` variable that cannot be reached from where you run this Jupyter notebook.\n", "* `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).\n", "* `zhmcclient.HTTPError`, if the password is the empty string.\n", "* 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)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import tututils\n", "import zhmcclient\n", "zhmc = '9.152.150.65' # edit this to your HMC's IP address or host name\n", "user = 'ensadmin' # edit this to the userid on that HMC\n", "client = tututils.make_client(zhmc, user)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The basic approach for handling exceptions with the zhmcclient package is the following:\n", "* Handle all exceptions derived from `zhmcclient.Error`.\n", "* Ignore all other exceptions (or let them be handled like you would handle programming errors)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "primary_cpc_name = 'CPC1'\n", "backup_cpc_name = 'CPC1B'\n", "try:\n", " cpc = client.cpcs.find(name=primary_cpc_name)\n", "except zhmcclient.NotFound:\n", " cpc = client.cpcs.find(name=backup_cpc_name)\n", "print(\"Using CPC {}\".format(cpc.name))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.5" } }, "nbformat": 4, "nbformat_minor": 1 }