Example #1
0
        private async Task ExecuteCommandAsync(int counter, Guid correlationId, ILogger logger, CommandRegistrationFindResult findResult, ICommand command, Stopwatch stopwatch, TimeSpan verificationElapsed, TimeSpan parsingElapsed, TimeSpan gatewayPing)
        {
            IDisposable typingState = null;

            if (findResult.Registration.Flags.HasFlag(CommandFlags.TypingIndicator))
            {
                typingState = command.Message.Channel.EnterTypingState();
            }

            var result = CommandResult.Failed;

            try
            {
                using (var scope = _clientServiceProvider.CreateScope())
                {
                    var module        = scope.ServiceProvider.GetRequiredService(findResult.Registration.ModuleType);
                    var commandLogger = _loggerFactory.CreateLogger(findResult.Registration.ModuleType)
                                        .WithCommandScope(command.Message, correlationId, findResult.Registration, findResult.Usage);

                    await findResult.Registration.Handler.Invoke(module, command, commandLogger, default); // TODO: cancellation
                }

                result = CommandResult.Succeeded;
            }
            catch (Exceptions.AbortException ex)
            {
                if (ex.Pages != null)
                {
                    await _communicator.CommandReply(command.Message.Channel, ex.Pages);
                }
                else if (!string.IsNullOrEmpty(ex.Message))
                {
                    await _communicator.CommandReply(command.Message.Channel, ex.Message);
                }

                result = CommandResult.Succeeded;
            }
            catch (Exceptions.IncorrectParametersCommandException ex)
            {
                await _communicator.CommandReplyIncorrectParameters(command.Message.Channel, findResult.Registration, ex.Message, findResult.Prefix, ex.ShowUsage);
            }
            catch (Exceptions.UnclearParametersCommandException ex)
            {
                await _communicator.CommandReplyUnclearParameters(command.Message.Channel, findResult.Registration, ex.Message, findResult.Prefix, ex.ShowUsage);
            }
            catch (Exceptions.MissingPermissionsException ex)
            {
                await _communicator.CommandReplyMissingPermissions(command.Message.Channel, findResult.Registration, ex.Permissions, ex.Message);
            }
            catch (Exceptions.MissingBotPermissionsException ex)
            {
                await _communicator.CommandReplyMissingBotPermissions(command.Message.Channel, findResult.Registration, ex.Permissions);
            }
            catch (Exceptions.MissingBotChannelPermissionsException ex)
            {
                await _communicator.CommandReplyMissingBotPermissions(command.Message.Channel, findResult.Registration, ex.Permissions);
            }
            catch (Exceptions.CommandException ex)
            {
                await _communicator.CommandReplyError(command.Message.Channel, ex.Message);
            }
            catch (Discord.Net.HttpException ex) when(ex.DiscordCode == 50001)
            {
                await _communicator.CommandReplyMissingBotAccess(command.Message.Channel, findResult.Registration);
            }
            catch (Discord.Net.HttpException ex) when(ex.DiscordCode == 50013)
            {
                await _communicator.CommandReplyMissingBotPermissions(command.Message.Channel, findResult.Registration);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Exception encountered while processing command {Command} (nr: {CommandCounter}) in module {Module}", findResult.Registration.PrimaryUsage.InvokeUsage, counter, findResult.Registration.ModuleType);
                await _communicator.CommandReplyGenericFailure(command.Message.Channel);
            }
            finally
            {
                if (typingState != null)
                {
                    typingState.Dispose();
                }
            }

            var totalElapsed = stopwatch.Elapsed;

            logger.LogInformation("Command {CommandCounter} {Result} in {TotalElapsed:F3}s (v: {VerificationElapsed:F3}s, p: {ParsingElapsed:F3}s, e: {ExecutionElapsed:F3}s, g: {GatewayDelay:F3}s)", counter, result, totalElapsed.TotalSeconds, verificationElapsed.TotalSeconds, (parsingElapsed - verificationElapsed).TotalSeconds, (totalElapsed - parsingElapsed).TotalSeconds, gatewayPing.TotalSeconds);
        }