public void TestRuntimeSequenceCommandBinding() { string jsonInjectorString = "[{\"Bind\":\"strange.unittests.ISimpleInterface\",\"To\":\"strange.unittests.SimpleInterfaceImplementer\", \"Options\":\"ToSingleton\"}]"; injectionBinder.ConsumeBindings(jsonInjectorString); string jsonCommandString = "[{\"Bind\":\"TestEvent\",\"To\":[\"strange.unittests.CommandWithInjection\",\"strange.unittests.CommandWithExecute\",\"strange.unittests.CommandWithoutExecute\"],\"Options\":\"InSequence\"}]"; commandBinder.ConsumeBindings(jsonCommandString); ICommandBinding binding = commandBinder.GetBinding("TestEvent") as ICommandBinding; Assert.IsTrue(binding.isSequence); TestDelegate testDelegate = delegate { commandBinder.ReactTo("TestEvent"); }; //That the exception is thrown demonstrates that the last command ran CommandException ex = Assert.Throws <CommandException> (testDelegate); Assert.AreEqual(ex.type, CommandExceptionType.EXECUTE_OVERRIDE); ISimpleInterface instance = injectionBinder.GetInstance <ISimpleInterface>() as ISimpleInterface; Assert.AreEqual(100, instance.intValue); }
public virtual object Execute(ExecutionInformation info, IReadOnlyList <ICommand> arguments, IReadOnlyList <Type> returnTypes) { // Make arguments lazy, we only want to execute them once arguments = arguments.Select(c => new LazyCommand(c)).ToArray(); CommandException contextException = null; foreach (var f in Functions) { // Try to call each overload try { return(f.Execute(info, arguments, returnTypes)); } catch (CommandException cmdEx) when(cmdEx.Reason == CommandExceptionReason.MissingParameter || cmdEx.Reason == CommandExceptionReason.MissingContext || cmdEx.Reason == CommandExceptionReason.NoReturnMatch) { // When we encounter a missing module problem we store it for later, as it is more helpful // im most cases to know that some commands *could* have matched if the module were there. if (cmdEx.Reason == CommandExceptionReason.MissingContext) { contextException = cmdEx; } } } if (contextException != null) { System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(contextException).Throw(); } throw new CommandException(strings.error_cmd_no_matching_overload, CommandExceptionReason.MissingParameter); }
public CommandExceptionEvent(IInvokeSource source, ParsedRequest request, CommandException exception) { this.Exception = exception; this.Source = source; this.Request = request; this.Handled = exception.Ignored; }
private void HandleException(CommandException ex, HttpContext context) { //TODO: opt ApiException apiException; switch (ex) { case UsernameConflictException e: apiException = new ApiException(HttpStatusCode.Conflict, "User exists", e); break; case UserNotFoundException e: apiException = new ApiException(HttpStatusCode.Unauthorized, "Invalid credentials", e); break; case InvalidPasswordException e: apiException = new ApiException(HttpStatusCode.Unauthorized, "Invalid credentials", e); break; case UnauthorizedAccessException e: apiException = new ApiException(HttpStatusCode.Unauthorized, "Unauthorize access", e); break; case InvalidCommandException e: apiException = new ApiException(HttpStatusCode.BadRequest, "Invalid command arguments"); break; default: apiException = new ApiException(HttpStatusCode.InternalServerError, "error", ex); break; } HandleException(apiException, context); }
public void Should_AssignPropertiesFromConstructor() { var exception = new CommandException("some message", 123, "MemberName"); Assert.Equal("some message", exception.Message); Assert.Equal(123, exception.Order); Assert.Equal("MemberName", exception.Name); }
/// <summary> /// Gets an exit code from exception. /// </summary> public static int FromException(Exception ex) { return(ex switch { CommandException cmdEx => cmdEx.ExitCode, DirectiveException dirEx => dirEx.ExitCode, TypinException _ => Error, _ => Error });
private async Task <IResult> ExecuteInternalAsync(string commandString, object[] args, IServiceProvider services) { try { var task = _action(commandString, args, services, this); if (task is Task <IResult> resultTask) { var result = await resultTask.ConfigureAwait(false); if (result is RuntimeResult execResult) { return(execResult); } } else if (task is Task <ExecuteResult> execTask) { var result = await execTask.ConfigureAwait(false); return(result); } else { await task.ConfigureAwait(false); var result = ExecuteResult.FromSuccess(); } var executeResult = ExecuteResult.FromSuccess(); return(executeResult); } catch (Exception ex) { var originalEx = ex; while (ex is TargetInvocationException) //Happens with void-returning commands { ex = ex.InnerException; } var wrappedEx = new CommandException(this, commandString, ex); var result = ExecuteResult.FromError(ex); if (Module.Service._throwOnError) { if (ex == originalEx) { throw; } else { ExceptionDispatchInfo.Capture(ex).Throw(); } } return(result); } }
private BotEmbed CreateCommandErrorEmbed(CommandException exception, ErrorLogItem logItem) { return(new BotEmbed(DiscordClient.CurrentUser, Color.Red, "Při provádění příkazu došlo k chybě") .AddField("ID záznamu", logItem.ID.ToString(), true) .AddField("Kanál", $"<#{exception.Context.Channel.Id}>", true) .AddField("Uživatel", exception.Context.User.Mention, true) .AddField("Zpráva", $"```{exception.Context.Message.Content}```", false) .AddField(exception.InnerException.GetType().Name, $"```{exception}```", false)); }
public void CommandExceptionTest_001() { var Except = new CommandException("Message", 0x00, 0x01, "Name"); Assert.AreEqual(Except.Message, "Message"); Assert.AreEqual(Except.Cmd, 0x00); Assert.AreEqual(Except.SubCmd, 0x01); Assert.AreEqual(Except.Name, "Name"); }
/// <inheritdoc /> public async Task <EmbedBuilder> HandleErrorsAsync(CommandException commandException) { var context = commandException.Context; var message = context.Message.Content.ToLower(); var commandName = commandException.Command.Name; var exception = commandException.GetBaseException().Message; // If error is a Missing permissions error, send embedded error message. if (exception.Contains("The server responded with error 50013: Missing Permissions")) { if (context is SocketCommandContext commandContext) { var rolePermission = commandContext.Guild.CurrentUser.Roles.Select(x => x.Permissions).ToList(); var channelPermissions = commandContext.Guild.CurrentUser.GetPermissions(commandContext.Channel as IGuildChannel); var description = "Im missing the following permissions:"; if (!rolePermission.Any(x => x.ManageRoles)) { description += " **ManageRoles**"; } if (!channelPermissions.SendMessages) { description += " **SendMessages**"; } if (!channelPermissions.ViewChannel) { description += " **ReadMessages**"; } if (!channelPermissions.AttachFiles) { description += " **AttachFiles**"; } if (!channelPermissions.EmbedLinks) { description += " **EmbedLinks**"; } if (!channelPermissions.AddReactions) { description += " **AddReactions**"; } if (!channelPermissions.ReadMessageHistory) { description += " **ReadMessageHistory**"; } if (!channelPermissions.ManageMessages) { description += " **ManageMessages**"; } await commandContext.Channel.SendMessageAsync(description).ConfigureAwait(false); return(null); } } return(GetDefaultError(commandName, message, exception)); }
/// <summary> /// Asynchronously logs a Discord <see cref="CommandService" /> log message to the console and log file. /// This is generally used for capturing thrown command exceptions. /// </summary> /// <param name="logMsg"></param> /// <param name="cmdException"></param> /// <returns></returns> public static async Task LogAsync(LogMessage logMsg, CommandException cmdException) { string logP = LogPrefix(LogLvl.ERROR); string contents = $"{DateTime.Now.ToLongDateString()} {DateTime.Now.ToLongTimeString()} {logP} Exception thrown when executing command " + $"{cmdException.Command.Name} in guild {cmdException.Context.Guild.Id} by user {cmdException.Context.User.Id}:\n" + $"Inner Exception Message: {cmdException.InnerException?.Message ?? "NULL"}\n" + $"Stack Trace: {logMsg.Exception.StackTrace ?? "NULL"}"; await LogFinisher(contents); }
public void Constructor_with_2_arguments_should_work() { var command = new BsonDocument("command", 1); var exception = new CommandException("message", command); exception.Message.Should().Be("message"); exception.InnerException.Should().BeNull(); exception.Command.Equals(command).Should().BeTrue(); exception.Result.Should().BeNull(); }
public void TestMissingExecute() { ICommand command = new CommandWithoutExecute(); TestDelegate testDelegate = delegate() { command.Execute(); }; CommandException ex = Assert.Throws <CommandException> (testDelegate); Assert.That(ex.type == CommandExceptionType.EXECUTE_OVERRIDE); }
public void Constructor_with_4_arguments_should_work() { var command = new BsonDocument("command", 1); var result = new BsonDocument("result", 2); var innerException = new Exception("inner"); var exception = new CommandException("message", command, result, innerException); exception.Message.Should().Be("message"); exception.InnerException.Message.Should().Be("inner"); exception.Command.Equals(command).Should().BeTrue(); exception.Result.Equals(result).Should().BeTrue(); }
private async Task <CommandResult> RunAsyncInner( IEnumerable <string> args, string workingDir, IDictionary <string, string?> additionalEnv, Action <string>?onStandardOutput = null, Action <string>?onStandardError = null, EventLogFile?eventLogFile = null, CancellationToken cancellationToken = default) { var stdOutBuffer = new StringBuilder(); var stdOutPipe = PipeTarget.ToStringBuilder(stdOutBuffer); if (onStandardOutput != null) { stdOutPipe = PipeTarget.Merge(stdOutPipe, PipeTarget.ToDelegate(onStandardOutput)); } var stdErrBuffer = new StringBuilder(); var stdErrPipe = PipeTarget.ToStringBuilder(stdErrBuffer); if (onStandardError != null) { stdErrPipe = PipeTarget.Merge(stdErrPipe, PipeTarget.ToDelegate(onStandardError)); } var pulumiCmd = Cli.Wrap("pulumi") .WithArguments(PulumiArgs(args, eventLogFile), escape: true) .WithWorkingDirectory(workingDir) .WithEnvironmentVariables(PulumiEnvironment(additionalEnv, debugCommands: eventLogFile != null)) .WithStandardOutputPipe(stdOutPipe) .WithStandardErrorPipe(stdErrPipe) .WithValidation(CommandResultValidation.None); // we check non-0 exit code ourselves var pulumiCmdResult = await pulumiCmd.ExecuteAsync(cancellationToken); var result = new CommandResult( pulumiCmdResult.ExitCode, standardOutput: stdOutBuffer.ToString(), standardError: stdErrBuffer.ToString()); if (pulumiCmdResult.ExitCode != 0) { throw CommandException.CreateFromResult(result); } else { return(result); } }
private Task LogError(LogMessage msg) { CommandException ce = msg.Exception as CommandException; if (ce != null) { ce.Context.Channel.SendMessageAsync("", false, new EmbedBuilder() { Color = Color.Red, Title = msg.Exception.InnerException.GetType().ToString(), Description = "An error occured while executing last command.\nHere are some details about it: " + msg.Exception.InnerException.Message }.Build()); } return(Task.CompletedTask); }
private async Task HandleErrorAsync(IResult result, SocketCommandContext context, CommandException exception = null) { switch (result.Error) { case CommandError.Exception: if (exception != null && exception.InnerException != null) { _logger.LogError(exception.InnerException, $"Command Exception with: {exception.Command}"); } break; case CommandError.BadArgCount: await context.Channel.SendMessageAsync("", embed : new EmbedBuilder() { Color = SoraSocketCommandModule.Red, Title = $"{SoraSocketCommandModule.FAILURE_EMOJI} {result.ErrorReason}" }.Build()); break; case CommandError.UnknownCommand: break; case CommandError.ParseFailed: await context.Channel.SendMessageAsync("", embed : new EmbedBuilder() { Color = SoraSocketCommandModule.Red, Title = $"{SoraSocketCommandModule.FAILURE_EMOJI} Failed to parse the entered value(s)!", Description = $"Make sure you enter the correct Data type! If the command asks for a " + $"@mention then mention a user, if a command needs a number don't enter a word!" }.Build()); break; default: await context.Channel.SendMessageAsync("", embed : new EmbedBuilder() { Color = SoraSocketCommandModule.Red, Title = $"{SoraSocketCommandModule.FAILURE_EMOJI} Command failed unexpectedly. Creator was notified.", Description = $"Reason: {result.ErrorReason}" }.Build()); _logger.LogError($"Command {exception?.Command?.Name ?? "Unknown"} failed with an exception! (Reason: {result.ErrorReason})", exception?.InnerException ?? new Exception($"Exception was null, extra data: {result.ErrorReason}, {exception?.Message}")); break; } }
private async Task HandleExceptionAsync(CommandException e) { if (e == null) { return; } if (e.Exception is Discord.Net.HttpException ex && ex.HttpCode == HttpStatusCode.Forbidden) { await e.Context.ReplyAsync("Error! I didn't have permissions to do something. It's probably embeds, can you give me permission to embed links in this channel?"); return; } Console.WriteLine(e.Exception.ToString()); await e.Context.ReplyAsync($"An exception occurred while attempting to execute this command. Report this issue with ``{bot.Configuration.Prefix}issue <issue>``."); }
public Task LogError(LogMessage msg) { if (msg.Exception.InnerException != null && msg.Exception.InnerException.GetType() == typeof(NotAvailable)) { CommandException ex = (CommandException)msg.Exception; ex.Context.Channel.SendMessageAsync(Modules.Base.Sentences.NotAvailable(ex.Context.Guild.Id)); return(Task.CompletedTask); } Log(msg); CommandException ce = msg.Exception as CommandException; if (ce != null) { if (ravenClient != null) { ravenClient.Capture(new SentryEvent(new Exception(msg.Message + Environment.NewLine + ce.Context.Message, msg.Exception))); } ce.Context.Channel.SendMessageAsync("", false, new EmbedBuilder() { Color = Color.Red, Title = msg.Exception.InnerException.GetType().ToString(), Description = Modules.Base.Sentences.ExceptionThrown(ce.Context.Guild.Id, msg.Exception.InnerException.Message), Footer = new EmbedFooterBuilder() { Text = Modules.Base.Sentences.ExceptionReported(ce.Context.Guild.Id) } }.Build()); if (sendStats) { AddError(msg.Exception.InnerException.GetType().ToString()); } } else { if (ravenClient != null) { ravenClient.Capture(new SentryEvent(msg.Exception)); } if (sendStats) { AddError(msg.Exception != null ? msg.Exception.Message.GetType().ToString() : "Unknown error"); } } return(Task.CompletedTask); }
public static CommandBuffer Update <TSource>(this CommandBuffer buffer, TSource source, RelationHeader sourceHeader) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (buffer.Store == null) { throw CommandException.NoSchemaStoreAttached(); } IRelation relation = new Relation(buffer.Store.From(source), sourceHeader); buffer.Update(relation); return(buffer); }
public static CommandBuffer Update <TSource>(this CommandBuffer buffer, TSource source, IEnumerable <string> sourceHeader) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (buffer.Store == null) { throw CommandException.NoSchemaStoreAttached(); } ISchema schema = buffer.Store.GetSchema(typeof(TSource)); buffer.Update(source, schema.Select(sourceHeader)); return(buffer); }
public void Serialization_should_work() { var command = new BsonDocument("command", 1); var result = new BsonDocument("result", 2); var innerException = new Exception("inner"); var exception = new CommandException("message", command, result, innerException); var formatter = new BinaryFormatter(); using (var stream = new MemoryStream()) { formatter.Serialize(stream, exception); stream.Position = 0; var rehydrated = (CommandException)formatter.Deserialize(stream); rehydrated.Message.Should().Be("message"); rehydrated.InnerException.Message.Should().Be("inner"); rehydrated.Command.Equals(command).Should().BeTrue(); rehydrated.Result.Equals(result).Should().BeTrue(); } }
public void SubmitExecutionResult(int id, bool success, string result) { if (!CommandRegistry.TryGetValue(id, out var item)) { throw new ArgumentException("Command not found!"); } bool transitioned; if (success) { transitioned = item.Completion.TrySetResult(result); } else { var exception = new CommandException(result); transitioned = item.Completion.TrySetException(exception); } if (!transitioned) { throw new InvalidOperationException("Failed to update Command!"); } }
public void TestMultipleCommands() { //CommandWithInjection requires an ISimpleInterface injectionBinder.Bind <ISimpleInterface>().To <SimpleInterfaceImplementer> ().ToSingleton(); //Bind the trigger to the command commandBinder.Bind(SomeEnum.ONE).To <CommandWithInjection>().To <CommandWithExecute>().To <CommandWithoutExecute>(); TestDelegate testDelegate = delegate { commandBinder.ReactTo(SomeEnum.ONE); }; //That the exception is thrown demonstrates that the last command ran CommandException ex = Assert.Throws <CommandException> (testDelegate); Assert.AreEqual(ex.type, CommandExceptionType.EXECUTE_OVERRIDE); //That the value is 100 demonstrates that the first command ran ISimpleInterface instance = injectionBinder.GetInstance <ISimpleInterface>() as ISimpleInterface; Assert.AreEqual(100, instance.intValue); }
public static CommandBuffer Update(this CommandBuffer buffer, IRelation relation) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (relation == null) { throw new ArgumentNullException(nameof(buffer)); } if (buffer.Store == null) { throw CommandException.NoSchemaStoreAttached(); } using IDataReader dataReader = relation.GetDataReader(); buffer.Update(dataReader); return(buffer); }
private Task LogError(LogMessage msg) { if (ravenClient == null) { Log(msg); } else { ravenClient.Capture(new SentryEvent(msg.Exception)); } CommandException ce = msg.Exception as CommandException; if (ce != null) { ce.Context.Channel.SendMessageAsync("", false, new EmbedBuilder() { Color = Color.Red, Title = msg.Exception.InnerException.GetType().ToString(), Description = Sentences.Error(ce.Context.Guild.Id, msg.Exception.InnerException.Message) }.Build()); } return(Task.CompletedTask); }
public void TestSequence() { //CommandWithInjection requires an ISimpleInterface injectionBinder.Bind <ISimpleInterface>().To <SimpleInterfaceImplementer>().ToSingleton(); //Bind the trigger to the command commandBinder.Bind <NoArgSignal>().To <CommandWithInjection>().To <CommandWithExecute>().To <CommandWithoutExecute>().InSequence(); TestDelegate testDelegate = delegate { NoArgSignal signal = injectionBinder.GetInstance <NoArgSignal>() as NoArgSignal; signal.Dispatch(); }; //That the exception is thrown demonstrates that the last command ran CommandException ex = Assert.Throws <CommandException>(testDelegate); Assert.AreEqual(ex.type, CommandExceptionType.EXECUTE_OVERRIDE); //That the value is 100 demonstrates that the first command ran ISimpleInterface instance = injectionBinder.GetInstance <ISimpleInterface>() as ISimpleInterface; Assert.AreEqual(100, instance.intValue); }
private int ExecuteCommand( ICommand TargetCommand, string[] Arguments, bool bWaitIfNeeded) { if ( TargetCommand is ISingleInstanceCommand ) { bool bAllowExecute = Monitor.TryEnter( TargetCommand.GetType(), bWaitIfNeeded ? Timeout.Infinite : 0 ); if ( ! bAllowExecute ) { CommandException ExecutionError = new CommandException(); throw ExecutionError; } } int CommandStatus; System.Exception ProcessError = null; SetInputMode( InputMode.Redirected ); _CommandList.Add( TargetCommand ); CommandArgument[] commandArguments = GenerateArguments( Arguments ); try { ICommandResult commandResult; CommandStatus = TargetCommand.PerformCommand( commandArguments, out commandResult ); } catch ( System.Exception ProcessException) { CommandStatus = 0; ProcessError = ProcessException; } bool bRequiresParent = false; bool bExternal = false; try { bRequiresParent = TargetCommand.RequiresParentTerminal(); } catch { } if ( TargetCommand is ExternalCommand ) { bExternal = true; if ( ! bRequiresParent ) { ( (ExternalCommand) TargetCommand ).Disconnect(); } } if ( ! bExternal || ! bRequiresParent ) { _CommandList.Remove( TargetCommand ); } if ( ! bRequiresParent ) { SetInputMode( InputMode.Native ); } if ( TargetCommand is ISingleInstanceCommand ) { Monitor.Exit( TargetCommand.GetType() ); } if ( null != ProcessError ) { throw ProcessError; } return CommandStatus; }
public async Task <CommandResult> RunAsync( IEnumerable <string> args, string workingDir, IDictionary <string, string> additionalEnv, Action <string>?onStandardOutput = null, Action <string>?onStandardError = null, CancellationToken cancellationToken = default) { // all commands should be run in non-interactive mode. // this causes commands to fail rather than prompting for input (and thus hanging indefinitely) var completeArgs = args.Concat(new[] { "--non-interactive" }); var env = new Dictionary <string, string>(); foreach (var element in Environment.GetEnvironmentVariables()) { if (element is KeyValuePair <string, object> pair && pair.Value is string valueStr) { env[pair.Key] = valueStr; } } foreach (var pair in additionalEnv) { env[pair.Key] = pair.Value; } using var proc = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo { FileName = "pulumi", WorkingDirectory = workingDir, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, }, }; foreach (var arg in completeArgs) { proc.StartInfo.ArgumentList.Add(arg); } foreach (var pair in env) { proc.StartInfo.Environment[pair.Key] = pair.Value; } var standardOutputBuilder = new StringBuilder(); proc.OutputDataReceived += (_, @event) => { if (@event.Data != null) { standardOutputBuilder.AppendLine(@event.Data); onStandardOutput?.Invoke(@event.Data); } }; var standardErrorBuilder = new StringBuilder(); proc.ErrorDataReceived += (_, @event) => { if (@event.Data != null) { standardErrorBuilder.AppendLine(@event.Data); onStandardError?.Invoke(@event.Data); } }; var tcs = new TaskCompletionSource <CommandResult>(); using var cancelRegistration = cancellationToken.Register(() => { // if the process has already exited than let's // just let it set the result on the task if (proc.HasExited || tcs.Task.IsCompleted) { return; } // setting it cancelled before killing so there // isn't a race condition to the proc.Exited event tcs.TrySetCanceled(cancellationToken); try { proc.Kill(); } catch { // in case the process hasn't started yet // or has already terminated } }); proc.Exited += (_, @event) => { // this seems odd, since the exit event has been triggered, but // the exit event being triggered does not mean that the async // output stream handlers have ran to completion. this method // doesn't exit until they have, at which point we can be sure // we have captured the output in its entirety. // note that if we were to pass an explicit wait time to this // method it would not wait for the stream handlers. // see: https://github.com/dotnet/runtime/issues/18789 proc.WaitForExit(); var result = new CommandResult( proc.ExitCode, standardOutputBuilder.ToString(), standardErrorBuilder.ToString()); if (proc.ExitCode != 0) { var ex = CommandException.CreateFromResult(result); tcs.TrySetException(ex); } else { tcs.TrySetResult(result); } }; proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); return(await tcs.Task.ConfigureAwait(false)); }
private static void ReturnError(CommandException ex, HttpListenerResponse response) { var jsonError = new JsonError(ex.Message, ex.Reason); switch (ex.Reason) { case CommandExceptionReason.Unknown: case CommandExceptionReason.InternalError: response.StatusCode = (int)HttpStatusCode.InternalServerError; return; case CommandExceptionReason.Unauthorized: response.StatusCode = (int)HttpStatusCode.Unauthorized; break; case CommandExceptionReason.MissingRights: jsonError.HelpLink = "https://github.com/Splamy/TS3AudioBot/wiki/FAQ#missing-rights"; response.StatusCode = (int)HttpStatusCode.Forbidden; break; case CommandExceptionReason.AmbiguousCall: case CommandExceptionReason.MissingParameter: case CommandExceptionReason.NotSupported: response.StatusCode = (int)HttpStatusCode.BadRequest; break; case CommandExceptionReason.MissingContext: if (ex is MissingContextCommandException mcex) { if (mcex.MissingType == typeof(InvokerData)) { jsonError.HelpMessage += "You have to authenticate yourself to call this method."; jsonError.HelpLink = "https://github.com/Splamy/TS3AudioBot/wiki/WebAPI#authentication"; } else if (mcex.MissingType == typeof(UserSession)) { jsonError.HelpMessage += "Creating UserSessions via api is currently not implemented yet."; } else if (mcex.MissingType == typeof(Bot) || mcex.MissingType == typeof(IPlayerConnection) || mcex.MissingType == typeof(PlayManager) || mcex.MissingType == typeof(Ts3Client) || mcex.MissingType == typeof(IVoiceTarget) || mcex.MissingType == typeof(IVoiceTarget)) { jsonError.HelpMessage += "You are trying to call a command which is specific to a bot. " + "Use '!bot use' to switch to a bot instance"; jsonError.HelpLink = "https://github.com/Splamy/TS3AudioBot/wiki/FAQ#api-missing-context"; } } goto case CommandExceptionReason.CommandError; case CommandExceptionReason.CommandError: case CommandExceptionReason.NoReturnMatch: response.StatusCode = 422; // Unprocessable Entity break; case CommandExceptionReason.FunctionNotFound: response.StatusCode = (int)HttpStatusCode.NotFound; break; default: throw Util.UnhandledDefault(ex.Reason); } using (var responseStream = new StreamWriter(response.OutputStream)) responseStream.Write(JsonConvert.SerializeObject(jsonError, ErrorSerializeSettings)); }
public async Task <CommandResult> RunAsync( IEnumerable <string> args, string workingDir, IDictionary <string, string> additionalEnv, Action <string>?onOutput = null, CancellationToken cancellationToken = default) { // all commands should be run in non-interactive mode. // this causes commands to fail rather than prompting for input (and thus hanging indefinitely) var completeArgs = args.Concat(new[] { "--non-interactive" }); var env = new Dictionary <string, string>(); foreach (var element in Environment.GetEnvironmentVariables()) { if (element is KeyValuePair <string, object> pair && pair.Value is string valueStr) { env[pair.Key] = valueStr; } } foreach (var pair in additionalEnv) { env[pair.Key] = pair.Value; } using var proc = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo { FileName = "pulumi", WorkingDirectory = workingDir, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, }, }; foreach (var arg in completeArgs) { proc.StartInfo.ArgumentList.Add(arg); } foreach (var pair in env) { proc.StartInfo.Environment[pair.Key] = pair.Value; } var standardOutputBuilder = new StringBuilder(); proc.OutputDataReceived += (_, @event) => { if (@event.Data != null) { standardOutputBuilder.AppendLine(@event.Data); onOutput?.Invoke(@event.Data); } }; var tcs = new TaskCompletionSource <CommandResult>(); using var cancelRegistration = cancellationToken.Register(() => { // if the process has already exited than let's // just let it set the result on the task if (proc.HasExited || tcs.Task.IsCompleted) { return; } // setting it cancelled before killing so there // isn't a race condition to the proc.Exited event tcs.TrySetCanceled(cancellationToken); try { proc.Kill(); } catch { // in case the process hasn't started yet // or has already terminated } }); proc.Exited += async(_, @event) => { var code = proc.ExitCode; var stdErr = await proc.StandardError.ReadToEndAsync().ConfigureAwait(false); var result = new CommandResult(code, standardOutputBuilder.ToString(), stdErr); if (code != 0) { var ex = CommandException.CreateFromResult(result); tcs.TrySetException(ex); } else { tcs.TrySetResult(result); } }; proc.Start(); proc.BeginOutputReadLine(); return(await tcs.Task.ConfigureAwait(false)); }