Implemented error handler in dispatcher

(requested by @Oleg_Oleg_Oleg)
This commit is contained in:
Alex Root Junior 2017-09-15 00:11:32 +03:00
parent bac44d58a6
commit 534dea6de7
2 changed files with 104 additions and 53 deletions

View file

@ -3,7 +3,8 @@ import functools
import logging
import typing
from .filters import CommandsFilter, ContentTypeFilter, RegexpFilter, USER_STATE, generate_default_filters
from .filters import CommandsFilter, ContentTypeFilter, RegexpFilter, USER_STATE, generate_default_filters, \
ExceptionsFilter
from .handler import Handler
from .storage import BaseStorage, DisabledStorage, FSMContext
from .webhook import BaseResponse
@ -52,6 +53,8 @@ class Dispatcher:
self.updates_handler.register(self.process_update)
self.errors_handlers = Handler(self, once=False)
self._pooling = False
def __del__(self):
@ -93,6 +96,7 @@ class Dispatcher:
:param update:
:return:
"""
try:
self.last_update_id = update.update_id
has_context = context.check_configured()
if update.message:
@ -145,6 +149,11 @@ class Dispatcher:
state = self.storage.get_state(user=update.pre_checkout_query.from_user.id)
context.set_value(USER_STATE, await state)
return await self.pre_checkout_query_handlers.notify(update.pre_checkout_query)
except Exception as e:
err = await self.errors_handlers.notify(self, update, e)
if err:
return err
raise
async def start_pooling(self, timeout=20, relax=0.1, limit=None):
"""
@ -746,6 +755,35 @@ class Dispatcher:
return decorator
def register_errors_handler(self, callback, *, func=None, exception=None):
"""
Register errors handler
:param callback:
:param func:
:param exception: you can make handler for specific errors type
"""
filters_set = []
if func is not None:
filters_set.append(func)
if exception is not None:
filters_set.append(ExceptionsFilter(exception))
self.errors_handlers.register(callback, filters_set)
def errors_handler(self, *, func=None, exception=None):
"""
Decorator for registering errors handler
:param func:
:param exception: you can make handler for specific errors type
:return:
"""
def decorator(callback):
self.register_errors_handler(callback, func=func, exception=exception)
return callback
return decorator
def current_state(self, *,
chat: typing.Union[str, int, None] = None,
user: typing.Union[str, int, None] = None) -> FSMContext:

View file

@ -125,6 +125,19 @@ class StatesListFilter(StateFilter):
return False
class ExceptionsFilter(Filter):
def __init__(self, exception):
self.exception = exception
def check(self, dispatcher, update, exception):
try:
raise exception
except self.exception:
return True
except:
return False
def generate_default_filters(dispatcher, *args, **kwargs):
filters_set = []