|
Blog > Komentarze do wpisu
Własne strony błędów 404 i 500 na Google App Engine
Nic tak nie denerwuje jak brzydki, suchy i niewiele mówiący komunikat o błędzie generowany przez serwer. Dlatego każdy szanujący się serwis, czy też aplikacja internetowa musi posiadać własne strony błędów, spójne w wyglądzie z resztą serwisu, na których nasz użytkownik dowie się co się stało i co ma dalej robić.
Mimo, że w dokumentacji nie jest opisane wprost jak to zrobić ustawienie własnych stron błędów 404 i 500 w aplikacjach działających na Google App Engine jest bardzo proste. Zakładam, że aplikacja pisana jest w Pythonie z wykorzystaniem domyślnego webapp Framework. Strona 404 Wystarczy na końcu app.yaml wstawić: - url: .* script: main.py W ten sposób main.py obsługuje wszystkie żądania nie pasujące do wcześniejszych reguł. Najlepiej wydzielić Sheduled Tasks (cron) oraz Task Queues by zwiększyć ich wydajność. W main.py umieszczamy: from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app class Error404Handler(webapp.RequestHandler): def get(self): self.error(404) path = os.path.join(os.path.dirname(__file__), '404.html') self.response.out.write(template.render(path, locals()))ROUTES = [('/', MainHandler), # other handlers ('/.+', Error404Handler)] def main(): application = webapp.WSGIApplication(ROUTES, debug=True) run_wsgi_app(application) if __name__ == '__main__': main() Error404Handler obsłuży wszystkie żądania nie pasujące do wcześniejszych reguł. Ustawiony zostaje kod błędu 404 oraz wyświetlony szablon dla strony 404.html Błąd 500 O ile w trakcie testów aplikacji w środowisku deweloperskim wyświetlanie szczegółowych informacji o wyjątku, który spowodował błąd serwera jest pożądane, a wręcz konieczne by móc rozwiązać błędy tak pokazywanie informacji o wyjątkach użytkownikowi końcowemu jest co najmniej niewskazane. Najprostszym rozwiązaniem jest uruchamianie aplikacji na serwerze produkcyjnym z debug=False Jednak wpisywanie tego na sztywno nie jest zbyt wygodne - w środowisku testowym nadal chcemy widzieć informacje o wyjątkach. Dlatego dodajemy automatyczne rozpoznawanie środowiska deweloperskiego: import os DEBUG = os.environ['SERVER_SOFTWARE'].startswith('Dev') def main(): application = webapp.WSGIApplication(ROUTES, debug=DEBUG) run_wsgi_app(application) Nie rozwiązuje to nam problemu w pełni. Owszem, użytkownik nie zobaczy informacji o wyjątku, ale musimy jeszcze pokazać mu naszą stronę błędu zamiast domyślnej pokazywanej przez serwery produkcyjne GAE. Wykorzystamy do tego metodę handle_exception() klasy webapp.RequestHandler, która zostaje wywołana, gdy wystąpił wyjątek nieobsłużony w bloku try/except. Polecam tu napisanie własnej klasy dziedziczącej po webapp.RequestHandler, w której zaimplementujemy metodę handle_exception() - teraz kod obsługi błędów będzie wspólny dla wszystkich naszych handlerów. class RequestHandler(webapp.RequestHandler): def __init__(self): # some initialization common for all handlers pass def handle_exception(self, exception, debug_mode): if debug_mode: webapp.RequestHandler.handle_exception(self, exception, debug_mode) return self.error(500) path = os.path.join(os.path.dirname(__file__), '500.html') self.response.out.write(template.render(path, locals())) logging.exception(exception) # email the traceback import sys, traceback lines = ''.join(traceback.format_exception(*sys.exc_info())) from google.appengine.api import mail try: mail.send_mail_to_admins(sender='admin@your_app.com', subject='[Exception] %s' % self.request.uri, body = lines) except: pass W przypadku nieoczekiwanego błędu użytkownikowi zostanie wyświetlona nasza strona błędu, informacja o wyjątku zostanie zapisana w logach jak i przesłana na maila do administratorów by mogli szybko zareagować i rozwiązać problem. czwartek, 13 sierpnia 2009, kosciak1
TrackBack
|
|