interactions-py / interactions.py

A highly extensible, easy to use, and feature complete bot framework for Discord
https://interactions-py.github.io/interactions.py/
MIT License
834 stars 185 forks source link

feat: option to defer without raising errors #1661

Closed mifuyutsuki closed 4 months ago

mifuyutsuki commented 5 months ago

Pull Request Type

Description

Add a bool kwarg suppress_error (default False) to defer() (often ctx.defer()) in different instances of InteractionContext. If enabled, deferring an interaction response again will not raise an error, which is the current behavior of ctx.defer().

One example use case of this feature, which I use in a bot of mine, is using auto_defer(time_until_defer=...) and ctx.defer() together, making the command defer after either a certain point or a set time, whichever is reached first.

Technical Description

This feature moves/renames the current defer() to _defer() (note the underscore). The new defer() is a wrapper for _defer(), which would suppress relevant errors (AlreadyDeferred, AlreadyResponded, and HTTPException) using contextlib.suppress(). A similar method of error suppression is already used by AutoDefer.

Changes

Related Issues

Test Scenarios

Use the following callback coroutine to an interaction command (slash command, component, context menu, modal, hybrid slash command). Tested on all five.

async def test_cmd(ctx):
  await ctx.defer()
  try:
    await ctx.defer(suppress_error=True)
  except Exception as e:
    await ctx.send(f"Error raised: {type(e)}.")
  else:
    await ctx.send(f"No error.")

If suppress_error=False or unspecified: Command responds with "Error raised" for AlreadyDeferred. If suppress_error=True: Command responds with "No error".

Python Compatibility

Checklist