Flask開發技巧之異常處理
阿新 • • 發佈:2020-05-22
# Flask開發技巧之異常處理
[TOC]
本人平時開發中使用的,或者學習到的一些flask開發技巧整理,需要已有較為紮實的flask基礎。
## 1、Flask內建異常處理
要想在Flask中處理好異常,有一套自己的異常處理機制,首先,我們必須先知道Flask自己是如何處理異常的。去flask的原始碼裡找一找會發現,在flask原始碼的app.py檔案下,有很多會丟擲異常的方法,其中拿一個舉例:
```python
def handle_exception(self, e):
"""Default exception handling that kicks in when an exception
occurs that is not caught. In debug mode the exception will
be re-raised immediately, otherwise it is logged and the handler
for a 500 internal server error is used. If no such handler
exists, a default 500 internal server error message is displayed.
.. versionadded:: 0.3
"""
exc_type, exc_value, tb = sys.exc_info()
got_request_exception.send(self, exception=e)
handler = self._find_error_handler(InternalServerError())
if self.propagate_exceptions:
# if we want to repropagate the exception, we can attempt to
# raise it with the whole traceback in case we can do that
# (the function was actually called from the except part)
# otherwise, we just raise the error again
if exc_value is e:
reraise(exc_type, exc_value, tb)
else:
raise e
self.log_exception((exc_type, exc_value, tb))
if handler is None:
return InternalServerError()
return self.finalize_request(handler(e), from_error_handler=True)
```
我們發現在flask內部對於500異常,會丟擲這樣一個錯誤類`InternalServerError()`
```python
class InternalServerError(HTTPException):
......
```
至此我們發現flask內部異常通過繼承這個HTTPException類來處理,那麼這個HTTPException類就是我們研究的重點。
## 2、HTTPException類分析
```python
@implements_to_string
class HTTPException(Exception):
"""Baseclass for all HTTP exceptions. This exception can be called as WSGI
application to render a default error page or you can catch the subclasses
of it independently and render nicer error messages.
"""
code = None
description = None
def __init__(self, description=None, response=None):
super(HTTPException, self).__init__()
if description is not None:
self.description = description
self.response = response
@classmethod
def wrap(cls, exception, name=None):
"""Create an exception that is a subclass of the calling HTTP
exception and the ``exception`` argument.
The first argument to the class will be passed to the
wrapped ``exception``, the rest to the HTTP exception. If
``e.args`` is not empty and ``e.show_exception`` is ``True``,
the wrapped exception message is added to the HTTP error
description.
.. versionchanged:: 0.15.5
The ``show_exception`` attribute controls whether the
description includes the wrapped exception message.
.. versionchanged:: 0.15.0
The description includes the wrapped exception message.
"""
class newcls(cls, exception):
_description = cls.description
show_exception = False
def __init__(self, arg=None, *args, **kwargs):
super(cls, self).__init__(*args, **kwargs)
if arg is None:
exception.__init__(self)
else:
exception.__init__(self, arg)
@property
def description(self):
if self.show_exception:
return "{}\n{}: {}".format(
self._description, exception.__name__, exception.__str__(self)
)
return self._description
@description.setter
def description(self, value):
self._description = value
newcls.__module__ = sys._getframe(1).f_globals.get("__name__")
name = name or cls.__name__ + exception.__name__
newcls.__name__ = newcls.__qualname__ = name
return newcls
@property
def name(self):
"""The status name."""
from .http import HTTP_STATUS_CODES
return HTTP_STATUS_CODES.get(self.code, "Unknown Error")
def get_description(self, environ=None):
"""Get the description."""
return u"
") def get_body(self, environ=None): """Get the HTML body.""" return text_type( ( u'\n' u"\n" u"
%s
" % escape(self.description).replace("\n", "") def get_body(self, environ=None): """Get the HTML body.""" return text_type( ( u'\n' u"\n" u"