static void RaiseCrashedEvent(CrashedEventArgs e) { var h = Crashed; if (h != null) h(null, e); }
public static void LogAndReportCrash([CanBeNull] string message, [CanBeNull] string assembly, [CanBeNull] Exception exception, bool shutdownImminent) { if (message == null) message = "(null)"; if (assembly == null) assembly = "(null)"; if (exception == null) exception = new Exception("(null)"); Log(LogType.SeriousError, "{0}: {1}", message, exception); //bool submitCrashReport = ConfigKey.SubmitCrashReports.Enabled(); bool submitCrashReport = false; bool isCommon = CheckForCommonErrors(exception); // ReSharper disable EmptyGeneralCatchClause try { var eventArgs = new CrashedEventArgs(message, assembly, exception, submitCrashReport && !isCommon, isCommon, shutdownImminent); RaiseCrashedEvent(eventArgs); isCommon = eventArgs.IsCommonProblem; } catch { } // ReSharper restore EmptyGeneralCatchClause if (!submitCrashReport || isCommon) { return; } lock (CrashReportLock) { if (DateTime.UtcNow.Subtract(lastCrashReport).TotalSeconds < MinCrashReportInterval) { Log(LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent."); return; } lastCrashReport = DateTime.UtcNow; try { StringBuilder sb = new StringBuilder(); sb.Append("version=").Append(Uri.EscapeDataString(SpACraft.version)); 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.UTF8.GetBytes(sb.ToString()); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(CrashReportUri); 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; request.UserAgent = "SpACraft " + SpACraft.version; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(formData, 0, formData.Length); requestStream.Flush(); } string responseString; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { // ReSharper disable AssignNullToNotNullAttribute using (StreamReader reader = new StreamReader(responseStream)) { // ReSharper restore AssignNullToNotNullAttribute responseString = reader.ReadLine(); } } } request.Abort(); if (responseString != null && responseString.StartsWith("ERROR")) { Log(LogType.Error, "Crash report could not be processed by SpACraft.net."); } else { int referenceNumber; if (responseString != null && Int32.TryParse(responseString, out referenceNumber)) { Log(LogType.SystemActivity, "Crash report submitted (Reference #{0})", referenceNumber); } else { Log(LogType.SystemActivity, "Crash report submitted."); } } } catch (Exception ex) { Log(LogType.Warning, "Logger.SubmitCrashReport: {0}", ex.Message); } } }