esserer Umgang mit Fehlern im Tornado-Request-Handl
Es gibt zwei ähnliche Handler: AgeHandler1 und AgeHandler2. In der ersten lösen wir einfach eine bestimmte Ausnahme aus, um eine Fehlermeldung zurückzugeben, in der zweiten geben wir manuell eine Fehlermeldung zurück. Was halten Sie von diesen beiden Methoden? Welche Methode ist für ein großes Projekt vorzuziehen? Weitere bewährte Methoden?
import logging
import os.path
import traceback
from sys import exc_info
from tornado import web, options, ioloop
logger = logging.getLogger(__name__)
class MyAppException(Exception):
def __init__(self, message, code=400, *args, **kwargs):
self.message = message
self.code = code
return super(MyAppException, self).__init__(*args, **kwargs)
def __str__(self):
return self.message
class MyAppBaseHandler(web.RequestHandler):
def handle_exception(self, e):
exc_type, exc_obj, exc_tb = exc_info()
logger.error(''.join([line for line in traceback.format_exception(
exc_type, exc_obj, exc_tb)]))
if isinstance(exc_obj, MyAppException):
self.set_status(exc_obj.code)
self.write({'error': {
'message': u'{exc_obj}'.format(exc_obj=exc_obj.message)}})
else:
self.set_status(500)
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
self.write({'error': {
'message': u'{exc_obj} in {fname} at {line}'.format(
exc_obj=exc_obj, fname=fname, line=exc_tb.tb_lineno)}})
class AgeHandler1(MyAppBaseHandler):
def get(self):
try:
age = self.get_argument('age')
age = int(age)
if age < 1 or age > 200:
raise MyAppException('Wrong age value.')
self.write('Your age is {age}'.format(age=age))
except Exception as e:
self.handle_exception(e)
class AgeHandler2(MyAppBaseHandler):
def get(self):
age = self.get_argument('age')
age = int(age)
if age < 1 or age > 200:
self.set_status(400)
self.write('Wrong age value.')
return
self.write('Your age is {age}'.format(age=age))
class MyApplication(web.Application):
def __init__(self, **kwargs):
kwargs['handlers'] = [
web.url(r'/age1', AgeHandler1, name='age1'),
web.url(r'/age2', AgeHandler2, name='age2'),
]
kwargs['debug'] = False
super(MyApplication, self).__init__(**kwargs)
if __name__ == '__main__':
options.parse_command_line()
application = MyApplication()
application.listen(5000)
ioloop.IOLoop.instance().start()
Antworten:
"""
http://127.0.0.1:5000/age1
500: {"error": {"message": "HTTP 400: Bad Request (Missing argument age) in app.py at 44"}}
---
http://127.0.0.1:5000/age1?age=10
200: Your age is 10
---
http://127.0.0.1:5000/age1?age=201
400: {"error": {"message": "Wrong age value."}}
---
http://127.0.0.1:5000/age1?age=abc
500: {"error": {"message": "invalid literal for int() with base 10: 'abc' in app.py at 45"}}
http://127.0.0.1:5000/age2
400: <html><title>400: Bad Request</title><body>400: Bad Request</body></html>
---
http://127.0.0.1:5000/age2?age=10
200: Your age is 10
---
http://127.0.0.1:5000/age2?age=201
400: Wrong age value.
---
http://127.0.0.1:5000/age2?age=abc]
500: <html><title>500: Internal Server Error</title><body>500: Internal Server Error</body></html>
"""