440
Rozdział 11.
Obsługa kolejnych wyjątków
Obsługa innych błędów bazy danych
Funkcja
log_request
wykorzystuje menedżer kontekstu
UseDatabase
(zapewniany
przez moduł
DBcm
). Teraz, gdy zabezpieczyłeś już wywołanie tej funkcji, możesz się
zrelaksować, mając świadomość, że wszelkie problemy związane z bazą danych zostaną
przechwycone (i obsłużone) przez Twój przechwytujący wszystko kod obsługi wyjątków.
Jednak funkcja
log_request
to niejedyne miejsce, w którym Twoja aplikacja
komunikuje się z bazą danych. Innym jest funkcja
view_the_log
, która pobiera
zalogowane dane z bazy, a następnie wyświetla je na ekranie.
Przypomnij sobie kod funkcji
view_the_log
, który został zaprezentowany poniżej.
...
@app.route(‘/viewlog’)
@check_logged_in
def view_the_log() -> ‘html’:
with UseDatabase(app.config[‘dbconfig’]) as cursor:
_SQL = ”””select phrase, letters, ip, browser_string, results
from log”””
cursor.execute(_SQL)
contents = cursor.fetchall()
titles = (‘Fraza’ , ‘Litery’ , ‘Adres klienta’, ‘Agent użytkownika’, ‘Wyniki’)
return render_template(‘viewlog.html’,
the_title=’View Log’,
the_row_titles=titles,
the_data=contents,)
...
Cały ten kod
również powinien
być chroniony.
Również ten kod może zawieść, jako że także on komunikuje się z bazą danych pracującą
po stronie backendu. Jednak w przeciwieństwie do
log_request
funkcja
view_the_log
nie
jest wywoływana z poziomu kodu aplikacji
vsearch4web.py, lecz w Twoim imieniu wywołuje ją
framework Flask. Oznacza to, że nie możesz napisać kodu chroniącego to wywołanie, ponieważ
odbywa się ono w ramach frameworka, nie Twojego kodu.
Skoro nie możesz zabezpieczyć wywołania funkcji
view_the_log
, następnym dobrym
rozwiązaniem będzie ochrona kodu wewnątrz jej zestawu, a szczególnie fragmentu, w którym
następuje użycie menedżera kontekstu
UseDatabase
. Zanim zajmiemy się rozważeniem sposobu
zrobienia tego, zastanówmy się, co może tu pójść nie tak:
• Pracująca po stronie backendu baza danych może być niedostępna.
• Możesz nie być w stanie zalogować się do działającej bazy danych.
• Po udanym zalogowaniu się może zawieść wykonanie zapytania bazodanowego.
• Może się zdarzyć coś innego (niespodziewanego).
Przedstawiona powyżej lista potencjalnych problemów przypomina spis rzeczy, którymi
powinieneś był się martwić w przypadku funkcji
log_request
.
jesteś tutaj�
441
Obsługa wyjątków
Czy „więcej błędów” oznacza „więcej klauzul except”?
Dysponując już pewną wiedzą na temat konstrukcji
try-except
, moglibyśmy dodać do funkcji
view_the_log
trochę kodu w celu zabezpieczenia użycia menedżera kontekstu
UseDatabase
.
...
@app.route(‘/viewlog’)
@check_logged_in
def view_the_log() -> ‘html’:
try:
with UseDatabase(app.config[‘dbconfig’]) as cursor:
...
except Exception as err:
print(‘Coś poszło źle:’, str(err))
Pozostała część
kodu funkcji
powinna się
znaleźć tutaj.
Ten wyjątek zostaje
zgłoszony, gdy
Twój kod nie może
odnaleźć bazy danych
pracującej po stronie
backendu.
Kolejny kod obsługi
wyjątków, który
przechwytuje wszystko.
Ta strategia przechwytywania wszystkiego z pewnością działa (w końcu to właśnie
z niej korzystałeś w przypadku funkcji
log_request
). Sprawy się jednak skomplikują,
gdy zdecydujesz się zrobić coś innego niż implementować kod obsługi wyjątków, który
przechwytuje wszystko. Co będzie, gdy postanowisz reagować na jakiś konkretny błąd bazy
danych, taki jak ten, który pojawia się, gdy baza nie zostaje odnaleziona? Przypomnij sobie
z początku tego rozdziału, że baza MySQL zgłasza wyjątek
InterfaceError
, gdy dzieje się
coś takiego, jak pokazano poniżej.
Mógłbyś tu dodać klauzulę
except
związaną z wyjątkiem
InterfaceError
, jednak aby dało się
to zrobić, musiałbyś również zaimportować w swoim kodzie moduł
mysql.connector
, w którym
został zdefiniowany ten konkretny wyjątek.
Z pozoru nie wydaje się to wielkim problemem. W rzeczywistości jednak nim jest.
Get Python Rusz głową! Wydanie II now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.