summaryrefslogtreecommitdiff
path: root/docs/guide/api/error_handling.rst
blob: 6ad67a94b9f0fbca6c8a6fb11be40f8b87a788d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
==============
Error Handling
==============

GLib has its own method of handling errors using :obj:`GLib.Error`. These are
raised as Python exceptions, but with a few small differences.

It's common in Python for exception subclasses to be used (e.g.,
:obj:`ValueError` versus :obj:`IOError`) to distinguish different types of
errors. Libraries often define their own :obj:`Exception` subclasses, and library
users will handle these cases explicitly.

In GLib-using libraries, errors are all :obj:`GLib.Error` instances, with no
subclassing for different error types. Instead, every :obj:`GLib.Error`
instance has attributes that distinguish types of error:

* :attr:`domain` is the error domain, usually a string that you can covert to
  a `GLib` quark with :func:`GLib.quark_to_string`
* :attr:`code` identifies a specific error within the domain
* :attr:`message` is a human-readable description of the error

Error domains are defined per-module, and you can get an error domain from
:func:`*_error_quark` functions on the relevant module. For example, IO errors
from `Gio` are in the domain returned by :func:`Gio.io_error_quark`, and the
possible values for :attr:`code` are enumerated in :obj:`Gio.IOErrorEnum`.

Once you've caught a :obj:`GLib.Error`, you can call
:meth:`GLib.Error.matches` to see whether it matches the specific error you
want to handle.


Examples
--------

Catching a specific error:

.. code:: pycon

    >>> from gi.repository import GLib, Gio
    >>> f = Gio.File.new_for_path('missing-path')
    >>> try:
    ...     f.read()
    ... except GLib.Error as err:
    ...     if err.matches(Gio.io_error_quark(), Gio.IOErrorEnum.NOT_FOUND):
    ...         print('File not found')
    ...     else:
    ...         raise
    File not found