Browse Source

Add View.on_error callback for swallowed exceptions

pull/7023/head
Rapptz 4 years ago
parent
commit
876b1e0f3e
  1. 29
      discord/ui/view.py

29
discord/ui/view.py

@ -27,6 +27,7 @@ from typing import Any, Callable, ClassVar, Dict, Iterator, List, Optional, Sequ
from functools import partial from functools import partial
from itertools import groupby from itertools import groupby
import traceback
import asyncio import asyncio
import sys import sys
import time import time
@ -252,7 +253,8 @@ class View:
.. note:: .. note::
If an exception occurs within the body then the interaction If an exception occurs within the body then the interaction
check is considered failed. check then :meth:`on_error` is called and it is considered
a failure.
Parameters Parameters
----------- -----------
@ -273,18 +275,37 @@ class View:
""" """
pass pass
async def on_error(self, error: Exception, item: Item, interaction: Interaction) -> None:
"""|coro|
A callback that is called when an item's callback or :meth:`interaction_check`
fails with an error.
The default implementation prints the traceback to stderr.
Parameters
-----------
error: :class:`Exception`
The exception that was raised.
item: :class:`Item`
The item that failed the dispatch.
interaction: :class:`~discord.Interaction`
The interaction that led to the failure.
"""
print(f'Ignoring exception in view {self} for item {item}:', file=sys.stderr)
traceback.print_exception(error.__class__, error, error.__traceback__, file=sys.stderr)
async def _scheduled_task(self, state: Any, item: Item, interaction: Interaction): async def _scheduled_task(self, state: Any, item: Item, interaction: Interaction):
try: try:
allow = await self.interaction_check(interaction) allow = await self.interaction_check(interaction)
except Exception:
allow = False
if not allow: if not allow:
return return
await item.callback(interaction) await item.callback(interaction)
if not interaction.response._responded: if not interaction.response._responded:
await interaction.response.defer() await interaction.response.defer()
except Exception as e:
return await self.on_error(e, item, interaction)
def _start_listening(self, store: ViewStore) -> None: def _start_listening(self, store: ViewStore) -> None:
self._cancel_callback = partial(store.remove_view) self._cancel_callback = partial(store.remove_view)

Loading…
Cancel
Save