static void RaiseCrashedEvent( CrashEventArgs e ) { var h = Crashed; if( h != null ) h( null, e ); }
const int MinCrashReportInterval = 61; // minimum interval between submitting crash reports, in seconds public static void LogAndReportCrash( string message, string assembly, Exception exception, bool shutdownImminent ) { if( message == null ) message = "(null)"; if( assembly == null ) assembly = "(null)"; if( exception == null ) exception = new Exception( "(null)" ); Log( "{0}: {1}", LogType.SeriousError, message, exception ); bool submitCrashReport = ConfigKey.SubmitCrashReports.GetBool(); bool isCommon = CheckForCommonErrors( exception ); try { CrashEventArgs eventArgs = new CrashEventArgs( message, assembly, exception, submitCrashReport && !isCommon, isCommon, shutdownImminent ); RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; } catch { } if( !submitCrashReport || isCommon ) { return; } lock( CrashReportLock ) { if( DateTime.UtcNow.Subtract( lastCrashReport ).TotalSeconds < MinCrashReportInterval ) { Log( "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent.", LogType.Warning ); return; } lastCrashReport = DateTime.UtcNow; try { StringBuilder sb = new StringBuilder(); sb.Append( "version=" ).Append( Uri.EscapeDataString( Updater.CurrentRelease.VersionString ) ); sb.Append( "&message=" ).Append( Uri.EscapeDataString( message ) ); sb.Append( "&assembly=" ).Append( Uri.EscapeDataString( assembly ) ); sb.Append( "&runtime=" ); if( MonoCompat.IsMono ) { sb.Append( Uri.EscapeDataString( "Mono " + MonoCompat.MonoVersionString ) ); } else { sb.Append( Uri.EscapeDataString( "CLR " + Environment.Version ) ); } sb.Append( "&os=" ).Append( Environment.OSVersion.Platform + " / " + Environment.OSVersion.VersionString ); if( exception is TargetInvocationException ) { exception = (exception).InnerException; } else if( exception is TypeInitializationException ) { exception = (exception).InnerException; } sb.Append( "&exceptiontype=" ).Append( Uri.EscapeDataString( exception.GetType().ToString() ) ); sb.Append( "&exceptionmessage=" ).Append( Uri.EscapeDataString( exception.Message ) ); sb.Append( "&exceptionstacktrace=" ).Append( Uri.EscapeDataString( exception.StackTrace ) ); if( File.Exists( Paths.ConfigFileName ) ) { sb.Append( "&config=" ).Append( Uri.EscapeDataString( File.ReadAllText( Paths.ConfigFileName ) ) ); } else { sb.Append( "&config=" ); } string[] lastFewLines; lock( LogLock ) { lastFewLines = RecentMessages.ToArray(); } sb.Append( "&log=" ).Append( Uri.EscapeDataString( String.Join( Environment.NewLine, lastFewLines ) ) ); byte[] formData = Encoding.ASCII.GetBytes( sb.ToString() ); HttpWebRequest request = (HttpWebRequest)WebRequest.Create( CrashReportUrl ); ServicePointManager.Expect100Continue = false; request.Method = "POST"; request.Timeout = 15000; // 15s timeout request.ContentType = "application/x-www-form-urlencoded"; request.CachePolicy = new RequestCachePolicy( RequestCacheLevel.NoCacheNoStore ); request.ContentLength = formData.Length; using( Stream requestStream = request.GetRequestStream() ) { requestStream.Write( formData, 0, formData.Length ); requestStream.Flush(); } request.Abort(); Log( "Crash report submitted.", LogType.SystemActivity ); } catch( Exception ex ) { Log( "Logger.SubmitCrashReport: {0}", LogType.Warning, ex.Message ); } } }