You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I propose the addition of a new exception sopel.plugin.PluginAbort or similar that can be used by plugin authors to abort plugin event handling while also sending a fully-custom string error message via IRC.
Prompted by discussion in #sopel on Libera.chat on 9 Feb 2025, with reference to PHP's die() mechanism and sys.exit(), SystemExit in the Python stdlib. Discussion prompted by @half-duplex with participation from @dgw and myself.
Problems Solved
It is relatively common that plugin code wants to abort the handling of a command, event, etc. and it is also common that people¹ solve this problem by doing something like:
fromsopelimportplugin@plugin.command("thrust")defthrust(bot, trigger):
ifcannot_continue_predicate(trigger):
bot.say("Error: the turbo encabulator is not available")
returnFalseoperate_novertrunnion()
This leaves a pitfall where people¹ may forget to terminate control flow:
fromsopelimportplugin@plugin.command("thrust")defthrust(bot, trigger):
ifcannot_continue_predicate(trigger):
bot.say("Error: the turbo encabulator is not available")
# NOTE: NO RETURN! Control flow spills out of this block and will probably cause an exception.operate_novertrunnion()
I think it is reasonable to say that plugin authors often want to simultaneously express the semantics of "handling has stopped' and "send an error message to IRC". I propose the introduction of a dedicated exception, so that this code can be written as in the following section.
An exception would also make a plugin-level abort more convenient in cases where plugin call stacks get appreciably deep. I.e. the plugin author may detect some fatal error in helper code that does not have direct access to bot and desire a way to propagate an abort all the way to the top-level.
¹ it's me, I'm people
Alternatives
A function plugin.abort() or similar could be introduced to have the same effect. I think this may be a good idea with introduction of an exception, in the same fashion that sys.exit() is a helper that raises SystemExit for you.
@dgw has some reservations about introducing such a helper in plugin so it is possible this has some other home. I argue that plugin is a reasonable place to put it because the proposed feature is very specific to plugin author code, but I can see a valid design concern in keeping the existing suite of decorators separated from other machinery. Perhaps plugin should be a package with a plugin.error and plugin.decorators gathered into the package root to preserve existing API?
@Exirel proposed return bot.say("Custom error message") as an alternative idiom in existing API.
Notes
Implementation notes
In the bot core that handles plugin event dispatch, this feature couple be implemented by doing the moral equivalent of:
try:
call_handler(bot, trigger)
exceptPluginAbortasexc:
# more type-safety/consistency checking is probably a good idea here, contingent on APIbot.say(exc.args)
exceptExceptionasexc:
existing_behavior(exc)
Example usage
importrandomfromsopelimportpluginBARKS= ["arf!", "grrRRR", "yip yip!"]
@plugin.command("bark")defbark(bot, trigger):
bot.say(random_bark())
defrandom_bark() ->str:
roll=random.randint(1, 4)
ifroll==4:
# NOTE: this auxilliary helper does not have access to bot. This abort is not possible without plugin API redesign in the existing Sopel APIraiseplugin.PluginAbort("Cannot locate bark")
else:
returnrandom.choice(BARKS)
The text was updated successfully, but these errors were encountered:
Requested Feature
I propose the addition of a new exception
sopel.plugin.PluginAbort
or similar that can be used by plugin authors to abort plugin event handling while also sending a fully-custom string error message via IRC.Prompted by discussion in
#sopel
on Libera.chat on 9 Feb 2025, with reference to PHP'sdie()
mechanism andsys.exit(), SystemExit
in the Python stdlib. Discussion prompted by @half-duplex with participation from @dgw and myself.Problems Solved
It is relatively common that plugin code wants to abort the handling of a command, event, etc. and it is also common that people¹ solve this problem by doing something like:
This leaves a pitfall where people¹ may forget to terminate control flow:
I think it is reasonable to say that plugin authors often want to simultaneously express the semantics of "handling has stopped' and "send an error message to IRC". I propose the introduction of a dedicated exception, so that this code can be written as in the following section.
An exception would also make a plugin-level abort more convenient in cases where plugin call stacks get appreciably deep. I.e. the plugin author may detect some fatal error in helper code that does not have direct access to
bot
and desire a way to propagate an abort all the way to the top-level.¹ it's me, I'm people
Alternatives
A function
plugin.abort()
or similar could be introduced to have the same effect. I think this may be a good idea with introduction of an exception, in the same fashion thatsys.exit()
is a helper that raisesSystemExit
for you.@dgw has some reservations about introducing such a helper in
plugin
so it is possible this has some other home. I argue thatplugin
is a reasonable place to put it because the proposed feature is very specific to plugin author code, but I can see a valid design concern in keeping the existing suite of decorators separated from other machinery. Perhapsplugin
should be a package with aplugin.error
andplugin.decorators
gathered into the package root to preserve existing API?@Exirel proposed
return bot.say("Custom error message")
as an alternative idiom in existing API.Notes
Implementation notes
In the bot core that handles plugin event dispatch, this feature couple be implemented by doing the moral equivalent of:
Example usage
The text was updated successfully, but these errors were encountered: