public virtual void ScriptFinished(ScriptFinishedResult result, string error = null) { if (ChildScriptFailed && !ChildScriptErrorCaught) { error = "Terminate with failure"; result = ScriptFinishedResult.Error; EngineLogger.Fatal("Result Code: " + result.ToString()); } else { EngineLogger.Information("Result Code: " + result.ToString()); } //add result variable if missing var resultVar = VariableList.Where(f => f.VariableName == "taskt.Result").FirstOrDefault(); //handle if variable is missing if (resultVar == null) { resultVar = new ScriptVariable() { VariableName = "taskt.Result", VariableValue = "" }; } //check value var resultValue = resultVar.VariableValue.ToString(); if (error == null) { EngineLogger.Information("Error: None"); if (TaskModel != null && _serverSettings.ServerConnectionEnabled) { HttpServerClient.UpdateTask(TaskModel.TaskID, "Completed", "Script Completed Successfully"); } if (string.IsNullOrEmpty(resultValue)) { TasktResult = "Successfully Completed Script"; } else { TasktResult = resultValue; } } else { error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault().StackTrace; EngineLogger.Error("Error: " + error); if (TaskModel != null) { HttpServerClient.UpdateTask(TaskModel.TaskID, "Error", error); } TasktResult = error; } if (!TasktEngineUI.IsChildEngine) { EngineLogger.Dispose(); } _currentStatus = EngineStatus.Finished; ScriptFinishedEventArgs args = new ScriptFinishedEventArgs(); args.LoggedOn = DateTime.Now; args.Result = result; args.Error = error; args.ExecutionTime = _stopWatch.Elapsed; args.FileName = FileName; SocketClient.SendExecutionLog("Result Code: " + result.ToString()); SocketClient.SendExecutionLog("Total Execution Time: " + _stopWatch.Elapsed); //convert to json var serializedArguments = JsonConvert.SerializeObject(args); //write execution metrics if (EngineSettings.TrackExecutionMetrics && (FileName != null)) { string summaryLoggerFilePath = Path.Combine(Folders.GetFolder(FolderType.LogFolder), "taskt Execution Summary Logs.txt"); Logger summaryLogger = new Logging().CreateJsonFileLogger(summaryLoggerFilePath, Serilog.RollingInterval.Infinite); summaryLogger.Information(serializedArguments); if (!TasktEngineUI.IsChildEngine) { summaryLogger.Dispose(); } } Client.EngineBusy = false; if (_serverSettings.ServerConnectionEnabled) { HttpServerClient.CheckIn(); } ScriptFinishedEvent?.Invoke(this, args); }
public virtual void ScriptFinished(ScriptFinishedResult result, string error = null) { if (ChildScriptFailed && !ChildScriptErrorCaught) { error = "Terminate with failure"; result = ScriptFinishedResult.Error; Log.Fatal("Result Code: " + result.ToString()); } else { Log.Information("Result Code: " + result.ToString()); } //add result variable if missing var resultVar = EngineContext.Variables.Where(f => f.VariableName == "OpenBots.Result").FirstOrDefault(); //handle if variable is missing if (resultVar == null) { resultVar = new OBScriptVariable() { VariableName = "OpenBots.Result", VariableValue = "" } } ; //check value var resultValue = resultVar.VariableValue.ToString(); if (error == null) { Log.Information("Error: None"); if (string.IsNullOrEmpty(resultValue)) { EngineContext.TaskResult = "Successfully Completed Script"; } else { EngineContext.TaskResult = resultValue; } } else { if (ErrorsOccured.Count > 0) { error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault().StackTrace; } Log.Error("Error: " + error); EngineContext.TaskResult = error; } if ((EngineContext.ScriptEngine != null && !EngineContext.IsChildEngine) || (EngineContext.IsServerExecution && !EngineContext.IsServerChildExecution)) { Log.CloseAndFlush(); } EngineContext.CurrentEngineStatus = EngineStatus.Finished; ScriptFinishedEventArgs args = new ScriptFinishedEventArgs { LoggedOn = DateTime.Now, Result = result, Error = error, ExecutionTime = _stopWatch.Elapsed, FileName = EngineContext.FilePath }; //convert to json var serializedArguments = JsonConvert.SerializeObject(args); //write execution metrics if (EngineContext.EngineSettings.TrackExecutionMetrics && (EngineContext.FilePath != null)) { string summaryLoggerFilePath = Path.Combine(Folders.GetFolder(FolderType.LogFolder), "OpenBots Execution Summary Logs.txt"); Logger summaryLogger = new LoggingMethods().CreateJsonFileLogger(summaryLoggerFilePath, RollingInterval.Infinite); summaryLogger.Information(serializedArguments); if (!EngineContext.IsChildEngine) { summaryLogger.Dispose(); } } ScriptFinishedEvent?.Invoke(this, args); }
public void ExecuteCommand(ScriptAction command) { //get command ScriptCommand parentCommand = command.ScriptCommand; if (parentCommand.CommandName == "RunTaskCommand") { parentCommand.CurrentScriptBuilder = TasktEngineUI.CallBackForm; } //set LastCommadExecuted LastExecutedCommand = command.ScriptCommand; //update execution line numbers LineNumberChanged(parentCommand.LineNumber); //handle pause request if (parentCommand.PauseBeforeExecution && TasktEngineUI.IsDebugMode && !ChildScriptFailed) { ReportProgress("Pausing Before Execution"); _isScriptPaused = true; TasktEngineUI.IsHiddenTaskEngine = false; } //handle pause bool isFirstWait = true; while (_isScriptPaused) { //only show pause first loop if (isFirstWait) { _currentStatus = EngineStatus.Paused; ReportProgress("Paused on Line " + parentCommand.LineNumber + ": " + (parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue())); ReportProgress("[Please select 'Resume' when ready]"); isFirstWait = false; } if (_isScriptSteppedInto && parentCommand.CommandName == "RunTaskCommand") { parentCommand.IsSteppedInto = true; parentCommand.CurrentScriptBuilder = TasktEngineUI.CallBackForm; _isScriptSteppedInto = false; TasktEngineUI.IsHiddenTaskEngine = true; break; } else if (_isScriptSteppedOver || _isScriptSteppedInto) { _isScriptSteppedOver = false; _isScriptSteppedInto = false; break; } //wait Thread.Sleep(1000); } _currentStatus = EngineStatus.Running; //handle if cancellation was requested if (IsCancellationPending) { return; } //If Child Script Failed and Child Script Error not Caught, next command should not be executed if (ChildScriptFailed && !ChildScriptErrorCaught) { throw new Exception("Child Script Failed"); } //bypass comments if (parentCommand.CommandName == "AddCodeCommentCommand" || parentCommand.IsCommented) { ReportProgress($"Skipping Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue().ConvertUserVariableToString(this))}", parentCommand.LogLevel); return; } //report intended execution if (parentCommand.CommandName != "LogMessageCommand") { ReportProgress($"Running Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : parentCommand.GetDisplayValue())}", parentCommand.LogLevel); } //handle any errors try { //determine type of command if ((parentCommand.CommandName == "LoopNumberOfTimesCommand") || (parentCommand.CommandName == "LoopContinuouslyCommand") || (parentCommand.CommandName == "LoopCollectionCommand") || (parentCommand.CommandName == "BeginIfCommand") || (parentCommand.CommandName == "BeginMultiIfCommand") || (parentCommand.CommandName == "BeginTryCommand") || (parentCommand.CommandName == "BeginLoopCommand") || (parentCommand.CommandName == "BeginMultiLoopCommand") || (parentCommand.CommandName == "BeginRetryCommand" || (parentCommand.CommandName == "BeginSwitchCommand"))) { //run the command and pass bgw/command as this command will recursively call this method for sub commands command.IsExceptionIgnored = true; parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "SequenceCommand") { command.IsExceptionIgnored = true; parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "StopCurrentTaskCommand") { IsCancellationPending = true; return; } else if (parentCommand.CommandName == "ExitLoopCommand") { CurrentLoopCancelled = true; } else if (parentCommand.CommandName == "NextLoopCommand") { CurrentLoopContinuing = true; } else if (parentCommand.CommandName == "SetEngineDelayCommand") { //get property value var engineDelay = parentCommand.PropertyValues["v_EngineSpeed"].ToString(); //var setEngineCommand = (SetEngineDelayCommand)parentCommand; //var engineDelay = setEngineCommand.v_EngineSpeed.ConvertToUserVariable(this); var delay = int.Parse(engineDelay); //update delay setting EngineSettings.DelayBetweenCommands = delay; } else { //sleep required time Thread.Sleep(EngineSettings.DelayBetweenCommands); //run the command parentCommand.RunCommand(this); if (parentCommand.CommandName == "LogMessageCommand") { string displayValue = parentCommand.GetDisplayValue().Replace("Log Message ['", "").Replace("']", ""); string logMessage = displayValue.Split('-').Last().ConvertUserVariableToString(this); displayValue = displayValue.Replace(displayValue.Split('-').Last(), logMessage); ReportProgress($"Logging Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? _privateCommandLog : displayValue)}", parentCommand.LogLevel); } } } catch (Exception ex) { if (!(LastExecutedCommand.CommandName == "RethrowCommand")) { if (ChildScriptFailed) { ChildScriptFailed = false; ErrorsOccured.Clear(); } ErrorsOccured.Add(new ScriptError() { SourceFile = FileName, LineNumber = parentCommand.LineNumber, StackTrace = ex.ToString(), ErrorType = ex.GetType().Name, ErrorMessage = ex.Message }); } var error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault(); string errorMessage = $"Source: {error.SourceFile}, Line: {error.LineNumber} {parentCommand.GetDisplayValue()}, " + $"Exception Type: {error.ErrorType}, Exception Message: {error.ErrorMessage}"; //error occuured so decide what user selected if (ErrorHandlingAction != string.Empty) { switch (ErrorHandlingAction) { case "Continue Processing": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), LogEventLevel.Error); ReportProgress("Continuing Per Error Handling"); break; default: throw ex; } } else { if (!command.IsExceptionIgnored && TasktEngineUI.IsDebugMode) { //load error form if exception is not handled TasktEngineUI.CallBackForm.IsUnhandledException = true; TasktEngineUI.AddStatus("Pausing Before Exception"); DialogResult result = TasktEngineUI.CallBackForm.LoadErrorForm(errorMessage); ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), LogEventLevel.Error); TasktEngineUI.CallBackForm.IsUnhandledException = false; if (result == DialogResult.OK) { ReportProgress("Ignoring Per User Choice"); ErrorsOccured.Clear(); if (_isScriptSteppedIntoBeforeException) { TasktEngineUI.CallBackForm.IsScriptSteppedInto = true; _isScriptSteppedIntoBeforeException = false; } else if (_isScriptSteppedOverBeforeException) { TasktEngineUI.CallBackForm.IsScriptSteppedOver = true; _isScriptSteppedOverBeforeException = false; } TasktEngineUI.uiBtnPause_Click(null, null); } else if (result == DialogResult.Abort || result == DialogResult.Cancel) { ReportProgress("Continuing Per User Choice"); TasktEngineUI.CallBackForm.RemoveDebugTab(); TasktEngineUI.uiBtnPause_Click(null, null); throw ex; } //TODO: Add Break Option } else { throw ex; } } } }
public async Task ExecuteCommand(ScriptAction command) { //get command ScriptCommand parentCommand = command.ScriptCommand; if (parentCommand == null) { return; } //in RunFromThisCommand exection, determine if/while logic. If logic returns true, skip until reaching the selected command if (!parentCommand.ScopeStartCommand && parentCommand.LineNumber < EngineContext.StartFromLineNumber) { return; } //if the selected command is within a while/retry, reset starting line number so that previous commands within the scope run in the following iteration else if (!parentCommand.ScopeStartCommand && parentCommand.LineNumber == EngineContext.StartFromLineNumber) { EngineContext.StartFromLineNumber = 1; } if (EngineContext.ScriptEngine != null && (parentCommand.CommandName == "RunTaskCommand" || parentCommand.CommandName == "ShowMessageCommand")) { parentCommand.CurrentScriptBuilder = EngineContext.ScriptEngine.EngineContext.ScriptBuilder; } //set LastCommandExecuted LastExecutedCommand = command.ScriptCommand; //update execution line numbers LineNumberChanged(parentCommand.LineNumber); //handle pause request if (EngineContext.ScriptEngine != null && parentCommand.PauseBeforeExecution && EngineContext.IsDebugMode && !ChildScriptFailed) { ReportProgress("Pausing Before Execution"); _isScriptPaused = true; EngineContext.ScriptEngine.IsHiddenTaskEngine = false; } //handle pause bool isFirstWait = true; while (_isScriptPaused) { //only show pause first loop if (isFirstWait) { EngineContext.CurrentEngineStatus = EngineStatus.Paused; ReportProgress("Paused on Line " + parentCommand.LineNumber + ": " + (parentCommand.v_IsPrivate ? PrivateCommandLog : parentCommand.GetDisplayValue())); ReportProgress("[Please select 'Resume' when ready]"); isFirstWait = false; } if (_isScriptSteppedInto && parentCommand.CommandName == "RunTaskCommand") { parentCommand.IsSteppedInto = true; parentCommand.CurrentScriptBuilder = EngineContext.ScriptEngine.EngineContext.ScriptBuilder; _isScriptSteppedInto = false; EngineContext.ScriptEngine.IsHiddenTaskEngine = true; break; } else if (_isScriptSteppedOver || _isScriptSteppedInto) { _isScriptSteppedOver = false; _isScriptSteppedInto = false; break; } if (((Form)EngineContext.ScriptEngine).IsDisposed) { IsCancellationPending = true; break; } //wait Thread.Sleep(1000); } EngineContext.CurrentEngineStatus = EngineStatus.Running; //handle if cancellation was requested if (IsCancellationPending) { return; } //If Child Script Failed and Child Script Error not Caught, next command should not be executed if (ChildScriptFailed && !ChildScriptErrorCaught) { throw new Exception("Child Script Failed"); } //bypass comments if (parentCommand.CommandName == "AddCodeCommentCommand" || parentCommand.CommandName == "BrokenCodeCommentCommand" || parentCommand.IsCommented) { return; } //report intended execution if (parentCommand.CommandName != "LogMessageCommand") { ReportProgress($"Running Line {parentCommand.LineNumber}: {(parentCommand.v_IsPrivate ? PrivateCommandLog : parentCommand.GetDisplayValue())}"); } //handle any errors try { //determine type of command if ((parentCommand.CommandName == "LoopNumberOfTimesCommand") || (parentCommand.CommandName == "LoopContinuouslyCommand") || (parentCommand.CommandName == "BeginForEachCommand") || (parentCommand.CommandName == "BeginIfCommand") || (parentCommand.CommandName == "BeginMultiIfCommand") || (parentCommand.CommandName == "BeginTryCommand") || (parentCommand.CommandName == "BeginWhileCommand") || (parentCommand.CommandName == "BeginMultiWhileCommand") || (parentCommand.CommandName == "BeginDoWhileCommand") || (parentCommand.CommandName == "BeginRetryCommand") || (parentCommand.CommandName == "BeginSwitchCommand")) { //run the command and pass bgw/command as this command will recursively call this method for sub commands //TODO: Make sure that removing these lines doesn't create any other issues //command.IsExceptionIgnored = true; await parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "SequenceCommand") { //command.IsExceptionIgnored = true; await parentCommand.RunCommand(this, command); } else if (parentCommand.CommandName == "StopCurrentTaskCommand") { if (EngineContext.ScriptEngine != null && EngineContext.ScriptEngine.EngineContext.ScriptBuilder != null) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptRunning = false; } IsCancellationPending = true; return; } else if (parentCommand.CommandName == "BreakCommand") { CurrentLoopCancelled = true; } else if (parentCommand.CommandName == "ContinueCommand") { CurrentLoopContinuing = true; } else { //sleep required time Thread.Sleep(EngineContext.EngineSettings.DelayBetweenCommands); if (!parentCommand.v_ErrorHandling.Equals("None")) { ErrorHandlingAction = parentCommand.v_ErrorHandling; } else { ErrorHandlingAction = string.Empty; } //run the command try { await parentCommand.RunCommand(this); } catch (Exception ex) { switch (ErrorHandlingAction) { case "Ignore Error": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Error)); ReportProgress("Ignoring Per Error Handling"); break; case "Report Error": ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Error)); ReportProgress("Handling Error and Attempting to Continue"); throw ex; default: throw ex; } } } } catch (Exception ex) { if (!(LastExecutedCommand.CommandName == "RethrowCommand")) { if (ChildScriptFailed) { ChildScriptFailed = false; ErrorsOccured.Clear(); } ErrorsOccured.Add(new ScriptError() { SourceFile = EngineContext.FilePath, LineNumber = parentCommand.LineNumber, StackTrace = ex.ToString(), ErrorType = ex.GetType().Name, ErrorMessage = ex.Message }); } var error = ErrorsOccured.OrderByDescending(x => x.LineNumber).FirstOrDefault(); string errorMessage = $"Source: {error.SourceFile}, Line: {error.LineNumber} {parentCommand.GetDisplayValue()}, " + $"Exception Type: {error.ErrorType}, Exception Message: {error.ErrorMessage}"; if (EngineContext.ScriptEngine != null && !command.IsExceptionIgnored && EngineContext.IsDebugMode) { //load error form if exception is not handled EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsUnhandledException = true; EngineContext.ScriptEngine.AddStatus("Pausing Before Exception"); DialogResult result = DialogResult.OK; if (ErrorHandlingAction != "Ignore Error") { result = EngineContext.ScriptEngine.EngineContext.ScriptBuilder.LoadErrorForm(errorMessage); } ReportProgress("Error Occured at Line " + parentCommand.LineNumber + ":" + ex.ToString(), Enum.GetName(typeof(LogEventLevel), LogEventLevel.Debug)); EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsUnhandledException = false; if (result == DialogResult.OK) { ReportProgress("Ignoring Per User Choice"); ErrorsOccured.Clear(); if (_isScriptSteppedIntoBeforeException) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptSteppedInto = true; _isScriptSteppedIntoBeforeException = false; } else if (_isScriptSteppedOverBeforeException) { EngineContext.ScriptEngine.EngineContext.ScriptBuilder.IsScriptSteppedOver = true; _isScriptSteppedOverBeforeException = false; } EngineContext.ScriptEngine.uiBtnPause_Click(null, null); } else if (result == DialogResult.Abort || result == DialogResult.Cancel) { ReportProgress("Continuing Per User Choice"); EngineContext.ScriptEngine.EngineContext.ScriptBuilder.RemoveDebugTab(); EngineContext.ScriptEngine.uiBtnPause_Click(null, null); throw ex; } } else { throw ex; } } }