* Fix broken link (#11) * Fix typos and improve wording * Add information for IGuildUser + Add GetPermission sample + Add ModifyAsync remarks * Add information for IGuildChannel + Add ModifyAsync remarks + Add GetOverwritePermissionAsync examples * Add warning for Direction.Around * Fix indentations and references * Move IRole.ModifyAsync sample * Add information for IUser + Add example, remarks for Get(Default)AvatarUrl + Add example, remarks for GetOrCreateDMChannelAsync + Add missing remarks/summary/returns for other properties of the class * Change verbs used in IVoiceState summary/remarks * Add additional explanation for IGuildUser.RoleIds * Change verbs used in IMessage summary/remarks * Clarify IUserMessage Add/RemoveReactionAsync samples * Fix command handler sample typo * Add information for DiscordSocketConfig + Add remarks/example to the class + Add remarks to AlwaysDownloadUsers * Fix documentation for SlowMode * Add additional remarks for Guild/TextChannelProperties * Update DocFx.Plugins.LastModified to v1.2.0 This should drastically improve docfx build time. * Add missing dependencies * Update DocFx.Plugins.LastModified to v1.2.1 Improve performance * Update DocFx.Plugins.LastModified to v1.2.2 * Clarify deployment.md + Rewritten .NET Core deployment strategies for better clarification * Split deployment types into framework-dependent and self-contained * Clarify the benefits of using different types of publishing * Include a sample of how to execute dotnet application with the dotnet command in a TIP dialog for visibility * Update post-execution article and samples + This change is to reflect changes made in https://github.com/RogueException/Discord.Net/pull/1164, where CommandInfo is now passed into the CommandExecuted event as an Optional<T> * Update DocFX.Plugin.DescriptionGenerator to v1.1.1 * Adjust according to recent CommandExecuted changes See: +f549da50e0+6260749095* Add further documentation for https://github.com/RogueException/Discord.Net/pull/1037 * Add partial documentation for the precondition helper class * Include CHANGELOG.md in docs * Revise post-execution docs * Fix incorrect Optional<T> usage * Indent some sample code and add a comment reminding the user that the post-execution basic sample code is not ideal. * Streamline docs for Attachment + This commit also adds further explanation for why Embeds and Attachments are read-only collections * Add further documentation for MessageActivity and MessageApplication * Add caching-related docs to ISocketMessageChannel * Add missing documentation inheritance for SyncPermissionsAsync * Streamline documentation process This is done by changing the documentation of the implementations required by interfaces to redirect to the interface method instead (e.g., SocketDMChannel#GetMessagesAsync refer to IMessageChannel.GetMessagesAsync within the remarks of the method). * Cleanup92bf8363ca* Update src/Discord.Net.Core/Entities/Channels/Direction.cs Co-Authored-By: Still34 <341464@gmail.com> * Update src/Discord.Net.Core/Entities/Channels/Direction.cs Co-Authored-By: Still34 <341464@gmail.com> * Update src/Discord.Net.Core/Entities/Channels/GuildChannelProperties.cs Co-Authored-By: Still34 <341464@gmail.com> * Update src/Discord.Net.WebSocket/DiscordSocketConfig.cs Co-Authored-By: Still34 <341464@gmail.com> * Update according to PR suggestions * Reword sentences of deployment article for clarification & remove mention of portability * Fix typos/grammar errors within TextChannelProperties * Add the logo SVG to the page navbar * Implement changing logo image based on theme color using CSS background image * Add a favicon * use the purple logomark instead of white * hack? set the title to navbar svg to read "Discord.Net Docs"
120 lines
4.5 KiB
Markdown
120 lines
4.5 KiB
Markdown
---
|
|
uid: Guides.Commands.PostExecution
|
|
title: Post-command Execution Handling
|
|
---
|
|
|
|
# Post-execution Handling for Commands
|
|
|
|
When developing commands, you may want to consider building a
|
|
post-execution handling system so you can have finer control
|
|
over commands. Discord.Net offers several post-execution workflows
|
|
for you to work with.
|
|
|
|
If you recall, in the [Command Guide], we have shown the following
|
|
example for executing and handling commands,
|
|
|
|
[!code[Command Handler](samples/intro/command_handler.cs)]
|
|
|
|
You may notice that after we perform [ExecuteAsync], we store the
|
|
result and print it to the chat, essentially creating the most
|
|
fundamental form of a post-execution handler.
|
|
|
|
With this in mind, we could start doing things like the following,
|
|
|
|
[!code[Basic Command Handler](samples/post-execution/post-execution_basic.cs)]
|
|
|
|
However, this may not always be preferred, because you are
|
|
creating your post-execution logic *with* the essential command
|
|
handler. This design could lead to messy code and could potentially
|
|
be a violation of the SRP (Single Responsibility Principle).
|
|
|
|
Another major issue is if your command is marked with
|
|
`RunMode.Async`, [ExecuteAsync] will **always** return a successful
|
|
[ExecuteResult] instead of the actual result. You can learn more
|
|
about the impact in @FAQ.Commands.General.
|
|
|
|
## CommandExecuted Event
|
|
|
|
Enter [CommandExecuted], an event that was introduced in
|
|
Discord.Net 2.0. This event is raised whenever a command is
|
|
executed regardless of its execution status. This means this
|
|
event can be used to streamline your post-execution design,
|
|
is not prone to `RunMode.Async`'s [ExecuteAsync] drawbacks.
|
|
|
|
Thus, we can begin working on code such as:
|
|
|
|
[!code[CommandExecuted demo](samples/post-execution/command_executed_demo.cs)]
|
|
|
|
So now we have a streamlined post-execution pipeline, great! What's
|
|
next? We can take this further by using [RuntimeResult].
|
|
|
|
### RuntimeResult
|
|
|
|
`RuntimeResult` was initially introduced in 1.0 to allow
|
|
developers to centralize their command result logic.
|
|
In other words, it is a result type that is designed to be
|
|
returned when the command has finished its execution.
|
|
|
|
However, it wasn't widely adopted due to the aforementioned
|
|
[ExecuteAsync] drawback. Since we now have access to a proper
|
|
result-handler via the [CommandExecuted] event, we can start
|
|
making use of this class.
|
|
|
|
The best way to make use of it is to create your version of
|
|
`RuntimeResult`. You can achieve this by inheriting the `RuntimeResult`
|
|
class.
|
|
|
|
The following creates a bare-minimum required for a sub-class
|
|
of `RuntimeResult`,
|
|
|
|
[!code[Base Use](samples/post-execution/customresult_base.cs)]
|
|
|
|
The sky is the limit from here. You can add any additional information
|
|
you would like regarding the execution result.
|
|
|
|
For example, you may want to add your result type or other
|
|
helpful information regarding the execution, or something
|
|
simple like static methods to help you create return types easily.
|
|
|
|
[!code[Extended Use](samples/post-execution/customresult_extended.cs)]
|
|
|
|
After you're done creating your [RuntimeResult], you can
|
|
implement it in your command by marking the command return type to
|
|
`Task<RuntimeResult>`.
|
|
|
|
> [!NOTE]
|
|
> You must mark the return type as `Task<RuntimeResult>` instead of
|
|
> `Task<MyCustomResult>`. Only the former will be picked up when
|
|
> building the module.
|
|
|
|
Here's an example of a command that utilizes such logic:
|
|
|
|
[!code[Usage](samples/post-execution/customresult_usage.cs)]
|
|
|
|
And now we can check for it in our [CommandExecuted] handler:
|
|
|
|
[!code[Usage](samples/post-execution/command_executed_adv_demo.cs)]
|
|
|
|
## CommandService.Log Event
|
|
|
|
We have so far covered the handling of various result types, but we
|
|
have not talked about what to do if the command enters a catastrophic
|
|
failure (i.e., exceptions). To resolve this, we can make use of the
|
|
[CommandService.Log] event.
|
|
|
|
All exceptions thrown during a command execution are caught and sent
|
|
to the Log event under the [LogMessage.Exception] property
|
|
as a [CommandException] type. The [CommandException] class allows
|
|
us to access the exception thrown, as well as the context
|
|
of the command.
|
|
|
|
[!code[Logger Sample](samples/post-execution/command_exception_log.cs)]
|
|
|
|
[CommandException]: xref:Discord.Commands.CommandException
|
|
[LogMessage.Exception]: xref:Discord.LogMessage.Exception
|
|
[CommandService.Log]: xref:Discord.Commands.CommandService.Log
|
|
[RuntimeResult]: xref:Discord.Commands.RuntimeResult
|
|
[CommandExecuted]: xref:Discord.Commands.CommandService.CommandExecuted
|
|
[ExecuteAsync]: xref:Discord.Commands.CommandService.ExecuteAsync*
|
|
[ExecuteResult]: xref:Discord.Commands.ExecuteResult
|
|
[Command Guide]: xref:Guides.Commands.Intro |