12.7. Exception Define¶
12.7.1. Define Custom Exceptions¶
Class which inherits from
Exception
Exceptions should have
Error
at the end of their names
>>> class MyError(Exception):
... pass
>>>
>>>
>>> raise MyError
Traceback (most recent call last):
MyError
>>>
>>> raise MyError('More verbose description')
Traceback (most recent call last):
MyError: More verbose description
12.7.2. Example¶
>>> class InsufficientPrivileges(Exception):
... pass
>>>
>>>
>>> role = 'user'
>>>
>>> if role != 'admin':
... raise InsufficientPrivileges
Traceback (most recent call last):
InsufficientPrivileges
12.7.3. Use Case - 0x01¶
Django Framework Use-case of Custom Exceptions:
>>>
... from django.contrib.auth.models import User
>>>
>>>
>>> def login(request):
... username = request.POST.get('username')
... password = request.POST.get('password')
...
... try:
... user = User.objects.get(username, password)
... except User.DoesNotExist:
... print('Sorry, no such user in database')
12.7.4. Use Case - 0x02¶
Dragon
>>> class Dragon:
... def take_damage(self, damage):
... raise self.IsDead
...
... class IsDead(Exception):
... pass
>>>
>>>
>>> wawelski = Dragon()
>>>
>>> try:
... wawelski.take_damage(10)
... except Dragon.IsDead:
... print('Dragon is dead')
Dragon is dead
12.7.5. Use Case - 0x03¶
>>> from datetime import datetime
>>> from uuid import uuid1
>>> import logging
>>>
>>>
>>> logging.basicConfig(
... level='WARNING',
... datefmt='%Y-%m-%d %H:%M:%S',
... format='[{levelname}] {message}',
... style='{'
... )
>>>
>>>
>>> class MyError(Exception):
... def __init__(self, *args, **kwargs):
... self.name = self.__class__.__name__
... self.reason = self.args[0]
...
... # make a UUID based on the host ID and current time
... self.uuid = str(uuid1())
...
... # save when exception occurred
... self.when = datetime.now()
...
... # run normal processing of the exception
... super().__init__(*args, **kwargs)
>>>
>>>
>>> def run():
... raise MyError('Error, because it is not working')
>>>
>>>
>>> try:
... run()
... except Exception as error:
... name = self.name
... reason = self.reason
... when = error.when.strftime('%Y-%m-%d %H:%M:%S')
... identifier = error.uuid
...
... # you can write this error to the database
... # or print it on the stderr
... logging.error(f'Error happened: {name=}, {reason=}, {when=}, {identifier=}')
[ERROR] Error happened: name='MyError', reason='Error, because it is not working', when='1969-07-21 02:56:15', identifier='886a59c4-8431-11ec-95bc-acde48001122'
12.7.6. Assignments¶
"""
* Assignment: Exception Custom Exception
* Type: homework
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min
English:
1. Define custom exception `NegativeKelvinError`
2. Check value `value` passed to a `result` function
3. If `value` is lower than 0, raise `NegativeKelvinError`
4. Non-functional requirements:
a. Write solution inside `result` function
b. Mind the indentation level
5. Run doctests - all must succeed
Polish:
1. Zdefiniuj własny wyjątek `NegativeKelvinError`
2. Sprawdź wartość `value` przekazaną do funckji `result`
3. Jeżeli `value` jest mniejsze niż 0, podnieś `NegativeKelvinError`
4. Wymagania niefunkcjonalne:
a. Rozwiązanie zapisz wewnątrz funkcji `result`
b. Zwróć uwagę na poziom wcięć
5. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `class`
* `pass`
* `raise`
* `if`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> isclass(NegativeKelvinError)
True
>>> issubclass(NegativeKelvinError, Exception)
True
>>> result(1)
>>> result(0)
>>> result(-1)
Traceback (most recent call last):
exception_custom_a.NegativeKelvinError
"""
def result(value):
...
"""
* Assignment: Exception Custom Exception
* Type: homework
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min
English:
1. Define custom exception `IsDead`
2. Check value `health` passed to a `hero` function
3. If `health` is lower than 0, raise `IsDead`
4. Non-functional requirements:
a. Write solution inside `hero` function
b. Mind the indentation level
5. Run doctests - all must succeed
Polish:
1. Zdefiniuj własny wyjątek `IsDead`
2. Sprawdź wartość `health` przekazaną do funckji `hero`
3. Jeżeli `health` jest mniejsza niż 0, podnieś `IsDead`
4. Wymagania niefunkcjonalne:
a. Rozwiązanie zapisz wewnątrz funkcji `result`
b. Zwróć uwagę na poziom wcięć
5. Uruchom doctesty - wszystkie muszą się powieść
Hints:
* `class`
* `pass`
* `raise`
* `if`
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isclass
>>> isclass(IsDead)
True
>>> issubclass(IsDead, Exception)
True
>>> hero(1)
>>> hero(0)
>>> hero(-1)
Traceback (most recent call last):
exception_custom_b.IsDead
"""
def hero(health):
...