@@ -55,6 +55,28 @@ def async_func(*args, **kwargs):
5555 return async_func
5656
5757
58+ class DispatcherHandlerFlow (Exception ):
59+ """
60+ Dispatcher update processing manipulation exceptions are base on this class.
61+ """
62+ pass
63+
64+
65+ class DispatcherHandlerContinue (DispatcherHandlerFlow ):
66+ """
67+ If check Handler's check_updated returned true, but execution of handler raised this,
68+ then handlers checking will continue.
69+ """
70+ pass
71+
72+
73+ class DispatcherHandlerStop (DispatcherHandlerFlow ):
74+ """
75+ Raise this in handler to prevent execution any other handlers (even in different group).
76+ """
77+ pass
78+
79+
5880class Dispatcher (object ):
5981 """
6082 This class dispatches all kinds of updates to its registered handlers.
@@ -162,6 +184,9 @@ def _pooled(self):
162184 break
163185
164186 promise .run ()
187+ if isinstance (promise .exception , DispatcherHandlerFlow ):
188+ self .logger .warning ('DispatcherHandlerFlow is not supported with async '
189+ 'functions; func: %s' , promise .pooled_function .__name__ )
165190
166191 def run_async (self , func , * args , ** kwargs ):
167192 """
@@ -255,24 +280,29 @@ def process_update(self, update):
255280 Processes a single update.
256281
257282 Args:
258- update (:obj:`str` | :class:`telegram.Update`): The update to process.
283+ update (:obj:`str` | :class:`telegram.Update` | :class:`telegram.TelegramError`):
284+ The update to process.
259285 """
260286
261287 # An error happened while polling
262288 if isinstance (update , TelegramError ):
263289 self .dispatch_error (None , update )
264-
265- else :
266- for group in self . groups :
290+ return
291+ for group in self . groups :
292+ try :
267293 for handler in self .handlers [group ]:
268294 try :
269295 if handler .check_update (update ):
270- handler .handle_update (update , self )
296+ try :
297+ handler .handle_update (update , self )
298+ except DispatcherHandlerContinue :
299+ continue
271300 break
272- # Dispatch any errors
301+ except DispatcherHandlerFlow :
302+ raise
273303 except TelegramError as te :
274- self .logger .warn ('A TelegramError was raised while processing the '
275- 'Update.' )
304+ self .logger .warning ('A TelegramError was raised while processing the '
305+ 'Update.' )
276306
277307 try :
278308 self .dispatch_error (update , te )
@@ -287,6 +317,8 @@ def process_update(self, update):
287317 self .logger .exception ('An uncaught error was raised while '
288318 'processing the update' )
289319 break
320+ except DispatcherHandlerStop :
321+ break
290322
291323 def add_handler (self , handler , group = DEFAULT_GROUP ):
292324 """
@@ -297,14 +329,20 @@ def add_handler(self, handler, group=DEFAULT_GROUP):
297329
298330 A handler must be an instance of a subclass of :class:`telegram.ext.Handler`. All handlers
299331 are organized in groups with a numeric value. The default group is 0. All groups will be
300- evaluated for handling an update, but only 0 or 1 handler per group will be used.
332+ evaluated for handling an update, but only 0 or 1 handler per group will be used,
333+ except situations when :class:`telegram.DispatcherHandlerContinue` or
334+ :class:`telegram.DispatcherHandlerStop` were raised.
301335
302336 The priority/order of handlers is determined as follows:
303337
304338 * Priority of the group (lower group number == higher priority)
305339 * The first handler in a group which should handle an update will be
306340 used. Other handlers from the group will not be used. The order in
307341 which handlers were added to the group defines the priority.
342+ * If :class:`telegram.DispatcherHandlerContinue` was raised, then next handler in the
343+ same group will be called.
344+ * If :class:`telegram.DispatcherHandlerStop` was raised, then zero handlers (even
345+ from other groups) will called.
308346
309347 Args:
310348 handler (:class:`telegram.ext.Handler`): A Handler instance.
@@ -343,7 +381,7 @@ def add_error_handler(self, callback):
343381 Registers an error handler in the Dispatcher.
344382
345383 Args:
346- handler (:obj:`callable`): A function that takes ``Bot, Update, TelegramError`` as
384+ callback (:obj:`callable`): A function that takes ``Bot, Update, TelegramError`` as
347385 arguments.
348386 """
349387
@@ -354,7 +392,7 @@ def remove_error_handler(self, callback):
354392 Removes an error handler.
355393
356394 Args:
357- handler (:obj:`callable`): The error handler to remove.
395+ callback (:obj:`callable`): The error handler to remove.
358396 """
359397
360398 if callback in self .error_handlers :
@@ -365,7 +403,7 @@ def dispatch_error(self, update, error):
365403 Dispatches an error.
366404
367405 Args:
368- update (:obj:`str` | :class:`telegram.Update`): The update that caused the error
406+ update (:obj:`str` | :class:`telegram.Update` | None ): The update that caused the error
369407 error (:class:`telegram.TelegramError`): The Telegram error that was raised.
370408 """
371409
0 commit comments