|
1 | 1 | # License: MIT |
2 | 2 | # Copyright © 2022 Frequenz Energy-as-a-Service GmbH |
3 | 3 |
|
4 | | -"""Base exception classes.""" |
| 4 | +"""Base exception classes. |
| 5 | +
|
| 6 | +# Exceptions |
| 7 | +
|
| 8 | +All exceptions generated by this library inherit from the |
| 9 | +[`Error`][frequenz.channels.Error] exception. |
| 10 | +
|
| 11 | +Exceptions generated by channels inherit from the |
| 12 | +[`ChannelError`][frequenz.channels.ChannelError] exception. When there is an attempt to |
| 13 | +use a closed channel, a [`ChannelClosedError`][frequenz.channels.ChannelClosedError] |
| 14 | +exception is raised. |
| 15 | +
|
| 16 | +# Causes |
| 17 | +
|
| 18 | +When a exception is caused by another exception, for example if the underlying channel |
| 19 | +was closed while seding or receiving a message, the original exception will be |
| 20 | +available as the cause of the exception: |
| 21 | +
|
| 22 | +```python |
| 23 | +from frequenz.channels import Anycast, ChannelClosedError, SenderError |
| 24 | +
|
| 25 | +channel = Anycast[int](name="test-channel") |
| 26 | +sender = channel.new_sender() |
| 27 | +
|
| 28 | +try: |
| 29 | + await sender.send(42) |
| 30 | +except SenderError as error: |
| 31 | + match error.__cause__: |
| 32 | + case None: |
| 33 | + print("The message couldn't be sent for an known reason") |
| 34 | + case ChannelClosedError() as closed_error: |
| 35 | + print(f"The message couldn't be sent, channel closed: {closed_error}") |
| 36 | + case _ as unknown_error: |
| 37 | + print(f"The message couldn't be sent: {unknown_error}") |
| 38 | +``` |
| 39 | +
|
| 40 | +Tip: |
| 41 | + If you are using the async iteration interface for receivers, then you can |
| 42 | + access the cause of the |
| 43 | + [`ReceiverStoppedError`][frequenz.channels.ReceiverStoppedError] exception by |
| 44 | + explicitly calling [`receive()`][frequenz.channels.Receiver.receive] on the |
| 45 | + receiver after the iteration is done: |
| 46 | +
|
| 47 | + ```python |
| 48 | + from frequenz.channels import Anycast, ChannelClosedError, ReceiverStoppedError |
| 49 | +
|
| 50 | + channel = Anycast[int](name="test-channel") |
| 51 | + receiver = channel.new_receiver() |
| 52 | +
|
| 53 | + async for value in receiver: |
| 54 | + print(value) |
| 55 | + try: |
| 56 | + await receiver.receive() |
| 57 | + except ReceiverStoppedError as error: |
| 58 | + print("The receiver was stopped") |
| 59 | + match error.__cause__: |
| 60 | + case None: |
| 61 | + print("The receiver was stopped without a known reason") |
| 62 | + case ChannelClosedError() as closed_error: |
| 63 | + print(f"The channel was closed with error: {closed_error}") |
| 64 | + case _ as unknown_error: |
| 65 | + print(f"The receiver was stopped due to an unknown error: {unknown_error}") |
| 66 | + ``` |
| 67 | +""" |
5 | 68 |
|
6 | 69 | from typing import Any |
7 | 70 |
|
|
0 commit comments