using System; using System.Diagnostics; using System.Globalization; using System.Text; using System.Windows.Input; using Microsoft.Practices.Composite.Events; using Microsoft.Practices.Composite.Logging; using VisionCritical.Common.Contract; using VisionCritical.Shell.Core.Configuration; using VisionCritical.Shell.Core.Interfaces; using VisionCritical.Shell.Core.Model; using VisionCritical.Shell.Localization; using VisionCritical.Shell.Localization.Resources; using VisionCritical.Shell.UI.Controls; namespace VisionCritical.Shell.Modules.Services { public class ServiceResultErrorDialogHelper : IServiceResultErrorDialogHelper { private readonly IAuthenticationManager _authenticationManager; private readonly IErrorMessageProvider _errorMessageProvider; private readonly ILoggerFacade _loggerFacade; private readonly IContext _context; private readonly IEventAggregator _eventAggregator; public ServiceResultErrorDialogHelper(IAuthenticationManager authenticationManager, IErrorMessageProvider errorMessageProvider, ILoggerFacade loggerFacade, IContext context, IEventAggregator eventAggregator) { _authenticationManager = authenticationManager; _errorMessageProvider = errorMessageProvider; _loggerFacade = loggerFacade; _context = context; _eventAggregator = eventAggregator; } public void ShowError(IServiceResult result) { ShowError(result, true); } public void ShowError(IServiceResult result, bool forceLogOff) { switch (result.Code) { case ReturnCode.AuthenticationFailed: { //NOTE: We assume that the reason for authentication failing is that //the session has expired (as of this change, it is the only reason //other than exception) var messageBoxArgs = new MessageBoxArgs { Icon = MessageBoxIcon.Exclamation, Title = Messages.SessionExpired_title, Content = Messages.SessionExpired_message, Buttons = new[] { _errorMessageProvider.VcErrorDialog_button_login }, ResultHandler = x => _authenticationManager.LogOff() }; Log(messageBoxArgs.Content, Category.Warn, Priority.None); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowMessageBox(messageBoxArgs); break; } case ReturnCode.FreeTrialExpired: { var messageBoxArgs = new ErrorDialogArgs { IsOmnipotent = true, Title = Messages.FreeTrialExpired_title, Content = Messages.FreeTrialExpired_vcmessage, ResultHandler = x => _authenticationManager.LogOff() }; Log(messageBoxArgs.Content, Category.Warn, Priority.High); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.ObsoleteVersion: { var messageBoxArgs = new ErrorDialogArgs { Title = result.Message, Content = result.ToFormattedString() }; Log(messageBoxArgs.Content, Category.Warn, Priority.High); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.TimeoutException: { var messageBoxArgs = new MessageBoxArgs { Icon = MessageBoxIcon.Exclamation, Title = Messages.TimeoutExpired_title, Content = result.ToFormattedString() }; Log(messageBoxArgs.Content, Category.Warn, Priority.None); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowMessageBox(messageBoxArgs); break; } case ReturnCode.CommunicationException: { var messageBoxArgs = new ErrorDialogArgs { IsHtml = true, IsOmnipotent = true, Title = Messages.CommunicationException_title, Content = Messages.CommunicationException_message, Buttons = new[] { _errorMessageProvider.VcErrorDialog_button_restart }, ResultHandler = x => _authenticationManager.LogOff(), RequestNavigateEvent = (s, e) => { if ("GetSupport" == e.Hyperlink.NavigateUri.OriginalString) { ControlUtilities.ShellApp.GetSupport(); } } }; Log(messageBoxArgs.Content, Category.Warn, Priority.High); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.Default: { string logMessage = string.Format("The service you are calling has not set its return info. Fix the service call: {0}", result.Message); Log(logMessage, Category.Warn, Priority.None); Debug.Assert(false, logMessage); break; } case ReturnCode.InvalidResetPasswordToken: { var messageBoxArgs = new ErrorDialogArgs { IsHtml = true, IsOmnipotent = true, Content = Messages.InvalidPasswordResetToken_message, ResultHandler = x => ControlUtilities.ShellApp.ReloadApplication(true, true), }; var logMessage = string.Format(CultureInfo.InvariantCulture, "{0}\n{1}", messageBoxArgs.Content, result.ToFormattedString()); Log(logMessage, Category.Warn, Priority.None); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.GenericException: { var messageBoxArgs = new ErrorDialogArgs { IsHtml = true, IsOmnipotent = true, Title = _errorMessageProvider.VcErrorDialog_label_title, Content = _errorMessageProvider.VcErrorDialog_generic_label_message, }; Log(messageBoxArgs.Content, Category.Warn, Priority.None); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.CustomMessageException: { var messageBoxArgs = new ErrorDialogArgs { IsHtml = true, IsOmnipotent = true, Title = Messages.Support_errorConnectingTitle, Content = result.Message, }; Log(messageBoxArgs.Content, Category.Warn, Priority.None); DialogController.ShowErrorDialog(messageBoxArgs); break; } case ReturnCode.Exception: { var sb = new StringBuilder(); sb.AppendFormat(CultureInfo.InvariantCulture, "Date: {0:R}", DateTime.UtcNow); sb.AppendLine(); sb.AppendFormat(CultureInfo.InvariantCulture, "Tenant: {0:N}", (null == _context.Session ? Guid.Empty : _context.Session.Tenant.ObjectId)); sb.AppendLine(); sb.AppendFormat(CultureInfo.InvariantCulture, "User: {0:N}", (null == _context.Session ? Guid.Empty : _context.Session.User.ObjectId)); sb.AppendLine(); sb.AppendLine(new string('-', 15)); sb.AppendLine(VersionInfo.InterestingInfo(_eventAggregator)); sb.AppendLine(new string('-', 15)); sb.AppendFormat(CultureInfo.InvariantCulture, "Code: {0}", string.IsNullOrEmpty(result.Code) ? "-" : result.Code); sb.AppendLine(); sb.AppendFormat(CultureInfo.InvariantCulture, "Message: {0}", string.IsNullOrEmpty(result.Message) ? "-" : result.Message); var debugInfo = new StringBuilder(); debugInfo.AppendFormat(CultureInfo.InvariantCulture, "Exception: {0}", string.IsNullOrEmpty(result.Exception) ? "-" : result.Exception); if (null != result.LocalException) { debugInfo.AppendLine(new string('-', 15)); debugInfo.AppendFormat(CultureInfo.InvariantCulture, "Local Exception: {0}", result.LocalException); } var errorDialogArgs = new ErrorDialogArgs { Error = sb.ToString(), DebugInfo = debugInfo.ToString(), ResultHandler = x => { if (ControlUtilities.OperatingSystem.GetModifierKeys(ModifierKeys.Control) != Keyboard.Modifiers) { if (forceLogOff) { _authenticationManager.LogOff(); } else { ControlUtilities.ShellApp.ReloadApplication(false, true); } } } }; Log(debugInfo, Category.Exception, Priority.None); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(errorDialogArgs); DialogController.ShowErrorDialog(errorDialogArgs); break; } default: { var messageBoxArgs = new MessageBoxArgs { Icon = MessageBoxIcon.Error, Content = result.ToFormattedString() }; Log(messageBoxArgs.Content, Category.Warn, Priority.None); // TODO: use event aggregator //this.EventAggregator.GetEvent().Publish(messageBoxArgs); DialogController.ShowMessageBox(messageBoxArgs); break; } } } private void Log(object message, Category category, Priority priority) { // TODO: don't use Context... unfortunately because we are using constructor dependency // injection, it will take a week to update everything to include the new logger facade _loggerFacade.Log((null == message ? null : message.ToString()), category, priority); } } }