using System; using System.Diagnostics; using System.IO; using System.Windows.Forms; namespace ClassicalSharp { /// Displays a message box when an unhandled exception occurs /// and also logs it to a specified log file. public static class ErrorHandler { static string logFile = "crash.log"; /// Adds a handler for when a unhandled exception occurs, unless /// a debugger is attached to the process in which case this does nothing. public static void InstallHandler( string logFile ) { ErrorHandler.logFile = logFile; if( !Debugger.IsAttached ) AppDomain.CurrentDomain.UnhandledException += UnhandledException; } /// Additional text that should be logged to the log file /// when an unhandled exception occurs. public static string[] AdditionalInfo; static void UnhandledException( object sender, UnhandledExceptionEventArgs e ) { // So we don't get the normal unhelpful crash dialog on Windows. Exception ex = (Exception)e.ExceptionObject; string error = ex.GetType().FullName + ": " + ex.Message + Environment.NewLine + ex.StackTrace; bool wroteToCrashLog = true; try { using( StreamWriter writer = new StreamWriter( logFile, true ) ) { writer.WriteLine( "=== crash occurred ===" ); writer.WriteLine( "Time: " + DateTime.Now.ToString() ); writer.WriteLine( error ); writer.WriteLine(); if( AdditionalInfo != null ) { foreach( string l in AdditionalInfo ) writer.WriteLine( l ); writer.WriteLine(); } } } catch( Exception ) { wroteToCrashLog = false; } string message = wroteToCrashLog ? "The cause of the crash has been logged to \"" + logFile + "\". Please consider reporting the crash " + "(and the circumstances that caused it) to github.com/UnknownShadow200/ClassicalSharp/issues" : "Failed to write the cause of the crash to \"" + logFile + "\". Please consider reporting the crash " + "(and the circumstances that caused it) to github.com/UnknownShadow200/ClassicalSharp/issues" + Environment.NewLine + Environment.NewLine + error; MessageBox.Show( "Oh dear. ClassicalSharp has crashed." + Environment.NewLine + Environment.NewLine + message, "ClassicalSharp has crashed" ); Environment.Exit( 1 ); } /// Logs a handled exception that occured at the specified location to the log file. public static bool LogError( string location, Exception ex ) { string error = ex.GetType().FullName + ": " + ex.Message + Environment.NewLine + ex.StackTrace; return LogError( location, error ); } /// Logs an error that occured at the specified location to the log file. public static bool LogError( string location, string text ) { try { using( StreamWriter writer = new StreamWriter( logFile, true ) ) { writer.WriteLine( "=== handled error ===" ); writer.WriteLine( "Occured when: " + location ); writer.WriteLine( text ); writer.WriteLine(); } } catch( Exception ) { return false; } return true; } } }