<commit_before>﻿using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using GitMind.Common.MessageDialogs;
using GitMind.Utils;


namespace GitMind.Common
{
	internal static class ExceptionHandling
	{
		private static bool hasDisplayedErrorMessageBox;
		private static bool hasFailed;


		public static void Init()
		{
			// Add the event handler for handling UI thread exceptions to the event		
			Application.Current.DispatcherUnhandledException += (s, e) =>
				HandleException("dispatcher exception", e.Exception);

			// Add the event handler for handling non-UI thread exceptions to the event. 
			AppDomain.CurrentDomain.UnhandledException += (s, e) =>
			HandleException("app domain exception", e.ExceptionObject as Exception);

			// Log exceptions that hasn't been handled when a Task is finalized.
			TaskScheduler.UnobservedTaskException += (s, e) =>
				HandleException("unobserved task exception", e.Exception);
		}


		private static void HandleException(string errorType, Exception exception)
		{
			if (hasFailed)
			{
				return;
			}

			hasFailed = true;

			string errorMessage = $"Unhandled {errorType}";
			
			if (Debugger.IsAttached)
			{
				// NOTE: If you end up here a task resulted in an unhandled exception
				Debugger.Break();
			}
			else
			{
				Shutdown(errorMessage, exception);
			}
		}


		public static void Shutdown(string message, Exception e)
		{
			string errorMessage = $"{message}:\n{e}";
			Log.Error(errorMessage);

			var dispatcher = GetApplicationDispatcher();
			if (dispatcher.CheckAccess())
			{
				ShowExceptionDialog(errorMessage, e);
			}
			else
			{
				dispatcher.Invoke(() => ShowExceptionDialog(errorMessage, e));
			}

			if (Debugger.IsAttached)
			{
				Debugger.Break();
			}

			Environment.FailFast(errorMessage, e);
		}


		private static void ShowExceptionDialog(string errorMessage, Exception e)
		{
			if (hasDisplayedErrorMessageBox)
			{
				return;
			}

			hasDisplayedErrorMessageBox = true;

			Message.ShowError(
				Application.Current.MainWindow, errorMessage, "GitMind - Unhandled Exception");
		}


		private static Dispatcher GetApplicationDispatcher() =>
			Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
	}
}<commit_msg>Made the unhandled error dialog nicer<commit_after>﻿using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using GitMind.Common.MessageDialogs;
using GitMind.Settings;
using GitMind.Utils;


namespace GitMind.Common
{
	internal static class ExceptionHandling
	{
		private static readonly ICmd cmd = new Cmd();
		private static bool hasDisplayedErrorMessageBox;
		private static bool hasFailed;
		private static bool hasShutdown;

		public static void Init()
		{
			// Add the event handler for handling UI thread exceptions to the event		
			Application.Current.DispatcherUnhandledException += (s, e) =>
			{
				HandleException("dispatcher exception", e.Exception);
				e.Handled = true;
			};

			// Add the event handler for handling non-UI thread exceptions to the event. 
			AppDomain.CurrentDomain.UnhandledException += (s, e) =>
			{
				HandleException("app domain exception", e.ExceptionObject as Exception);
			};

			// Log exceptions that hasn't been handled when a Task is finalized.
			TaskScheduler.UnobservedTaskException += (s, e) =>
			{
				HandleException("unobserved task exception", e.Exception);
				e.SetObserved();
			};
		}


		private static void HandleException(string errorType, Exception exception)
		{
			if (hasFailed)
			{
				return;
			}

			hasFailed = true;

			string errorMessage = $"Unhandled {errorType}";
			
			if (Debugger.IsAttached)
			{
				// NOTE: If you end up here a task resulted in an unhandled exception
				Debugger.Break();
			}
			else
			{
				Shutdown(errorMessage, exception);
			}
		}


		public static void Shutdown(string message, Exception e)
		{
			if (hasShutdown)
			{
				return;
			}

			hasShutdown = true;

			string errorMessage = $"{message}:\n{e}";
			Log.Error(errorMessage);

			var dispatcher = GetApplicationDispatcher();
			if (dispatcher.CheckAccess())
			{
				ShowExceptionDialog(e);
			}
			else
			{
				dispatcher.Invoke(() => ShowExceptionDialog(e));
			}

			if (Debugger.IsAttached)
			{
				Debugger.Break();
			}

			Restart();

			Application.Current.Shutdown(0);
		}


		private static void ShowExceptionDialog(Exception e)
		{
			if (hasDisplayedErrorMessageBox)
			{
				return;
			}

			hasDisplayedErrorMessageBox = true;

			Message.ShowInfo(
				Application.Current.MainWindow,
				"Sorry, but some unexpected event occurred.\nPlease lets try again.",
				"GitMind");
		}


		private static void Restart()
		{
			string targetPath = ProgramPaths.GetInstallFilePath();
			cmd.Start(targetPath, "");
		}


		private static Dispatcher GetApplicationDispatcher() =>
			Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
	}
}
{'fraction_non_alphanumeric': 0.09865919551731038, 'fraction_numerical': 0.00020012007204322593, 'mean_word_length': 3.572735590118939, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1193271', 'n_tokens_mistral': 1790, 'n_tokens_neox': 1437, 'n_words': 386}