private static void GetErrorLogComplete(INTV.LtoFlash.Model.ErrorLog errorLog) { var message = "Retrieved error log:\n\n"; if (errorLog == null) { message += "<null>"; } else { message += errorLog.GetDetailedErrorReport(INTV.LtoFlash.Model.FirmwareRevisions.UnavailableFirmwareVersion); } INTV.Shared.View.OSMessageBox.Show(message, "Error Log Retrieved"); }
/// <summary> /// This is a general-purpose command completion routine for use with the asynchronous task system for executing commands on a Locutus device. /// </summary> /// <param name="taskData">The task data.</param> /// <remarks>This function will be called on the main thread when a Locutus command has finished executing. It will report whether the command /// successfully executed, and execute an optional callback upon success.</remarks> private static void OnComplete(AsyncTaskData taskData) { var data = (ExecuteDeviceCommandAsyncTaskData)taskData; #if REPORT_COMMAND_PERFORMANCE var portName = data.Device.Port == null ? "NO_PORT" : data.Device.Port.Name; try { #endif // REPORT_COMMAND_PERFORMANCE data.Device.IsCommandInProgress = false; data.ExitedCommand = true; data.Device.Port.LogPortMessage("<<<< ExecuteDeviceCommandAsyncTaskData COMPLETE: CommandInProgress: FALSE"); var exception = data.Error; var exceptionErrorDetail = data.DeviceExceptionDetail; var failureMessage = data.FailureMessage; var currentlyExecutingCommand = data.CurrentlyExecutingCommand; bool succeeded = data.Succeeded && (exception == null); if (succeeded && (data.OnSuccess != null)) { data.OnSuccess(data.Cancelled, data.DidShowProgress, data.Result); } var goIdle = !succeeded; if (goIdle) { data.Device.ConnectionState = ConnectionState.Idle; } if (!succeeded && (data.OnFailure != null)) { var errorMessageBuilder = new System.Text.StringBuilder(); errorMessageBuilder.Append(string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceCommand_Generic_FailedFormat, currentlyExecutingCommand)); if (!string.IsNullOrWhiteSpace(exceptionErrorDetail)) { if (errorMessageBuilder.Length > 0) { errorMessageBuilder.AppendLine(); } errorMessageBuilder.Append(exceptionErrorDetail.Trim()); } exceptionErrorDetail = errorMessageBuilder.ToString(); if (exception != null) { ErrorLog errorLog = null; var errorLogMessageString = string.Empty; if (exception is DeviceCommandExecuteFailedException) { try { data.Device.Port.LogPortMessage(">>>> ExecuteDeviceCommandAsyncTaskData COMPLETE: FETCH ERROR LOG: CommandInProgress: TRUE"); data.Device.IsCommandInProgress = true; var gotErrorSucceeded = false; errorLog = Commands.DownloadErrorLog.Instance.Execute(data.Device.Port, null, out gotErrorSucceeded) as ErrorLog; const int MaxDownloadErrorRetryCount = 3; for (int i = 0; !gotErrorSucceeded && (errorLog == null) && (i < MaxDownloadErrorRetryCount); ++i) { DebugOutput("Retry download error log attempt #" + i + 1); // Wait for a beacon and try again. if (data.Device.WaitForBeacon(ProtocolCommand.WaitForBeaconTimeout)) { errorLog = Commands.DownloadErrorLog.Instance.Execute(data.Device.Port, null, out gotErrorSucceeded) as ErrorLog; } } errorMessageBuilder.AppendLine(); if (gotErrorSucceeded) { if (errorLog.ErrorIds.All(id => id == ErrorLogId.Luigi)) { errorLogMessageString = Resources.Strings.ErrorLog_DecodeLuigiErrorMessage; } else { var errorLogContents = errorLog.GetDetailedErrorReport(data.Device.FirmwareRevisions.Current); if (string.IsNullOrWhiteSpace(errorLogContents)) { errorLogContents = Resources.Strings.ErrorBufferReport_Empty; } errorMessageBuilder.AppendLine().AppendFormat(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.ErrorBufferReport_Format, errorLogContents); errorLog = null; // we don't want to use the error log mechanism in this case } } else { errorMessageBuilder.AppendLine().AppendLine(Resources.Strings.ErrorBufferReport_FailedToRetrieve); } } catch (Exception e) { errorMessageBuilder.AppendLine().AppendLine(Resources.Strings.ErrorBufferReport_ThrewException).AppendLine().AppendLine(e.ToString()); } finally { data.Device.IsCommandInProgress = false; data.Device.Port.LogPortMessage(">>>> ExecuteDeviceCommandAsyncTaskData COMPLETE: FETCH ERROR LOG: CommandInProgress: FALSE"); } exceptionErrorDetail = errorMessageBuilder.ToString(); } if ((errorLog != null) && !string.IsNullOrEmpty(errorLogMessageString)) { exception = new DeviceCommandFailedException(errorLogMessageString, errorLog, exception as DeviceCommandExecuteFailedException); } else { exception = new DeviceCommandFailedException(currentlyExecutingCommand, exception, exceptionErrorDetail); } } else { exception = new DeviceCommandFailedException(currentlyExecutingCommand, exceptionErrorDetail); } if (string.IsNullOrWhiteSpace(failureMessage)) { var endOfFirstLine = exceptionErrorDetail.IndexOf(Environment.NewLine); if (endOfFirstLine > 0) { failureMessage = exceptionErrorDetail.Substring(0, endOfFirstLine).Trim(); } else { failureMessage = exceptionErrorDetail.Trim(); } } succeeded = data.OnFailure(failureMessage, exception); } if (goIdle) { data.Device.ConnectionState = ConnectionState.WaitForBeacon; } data.Dispose(); if (!succeeded) { if (string.IsNullOrWhiteSpace(failureMessage)) { throw new DeviceCommandFailedException(currentlyExecutingCommand, exception, exceptionErrorDetail); } else { throw new DeviceCommandFailedException(currentlyExecutingCommand, failureMessage, exception, exceptionErrorDetail); } } #if REPORT_COMMAND_PERFORMANCE } finally { data.Stopwatch.Stop(); DebugOutput(portName + ": DEVICECOMMAND FINISH: " + data.DoWorkMethodName + " DURATION: " + data.Stopwatch.Elapsed.ToString()); } #endif // REPORT_COMMAND_PERFORMANCE // I don't like doing this here -- it's too "UI-ey" for being in the Model, but // it fixes various problems and is easier than adding a universal 'on command complete' handler. INTV.Shared.ComponentModel.CommandManager.InvalidateRequerySuggested(); }