private void SetGlobalContext(int uiCultureLCID, int cultureLCID, string?serializedSession) { // set global telemetry session var session = GetTelemetrySession(serializedSession); if (session == null) { return; } EnsureCulture(uiCultureLCID, cultureLCID); // set roslyn loggers RoslynServices.SetTelemetrySession(session); RoslynLogger.SetLogger(AggregateLogger.Create(new VSTelemetryLogger(session), RoslynLogger.GetLogger())); // set both handler as NFW FatalError.Handler = ex => WatsonReporter.Report(ex, WatsonSeverity.Critical); FatalError.NonFatalHandler = ex => WatsonReporter.Report(ex); // start performance reporter var diagnosticAnalyzerPerformanceTracker = SolutionService.PrimaryWorkspace.Services.GetService <IPerformanceTrackerService>(); if (diagnosticAnalyzerPerformanceTracker != null) { var globalOperationNotificationService = SolutionService.PrimaryWorkspace.Services.GetService <IGlobalOperationNotificationService>(); _performanceReporter = new PerformanceReporter(Logger, diagnosticAnalyzerPerformanceTracker, globalOperationNotificationService, s_reportInterval, _shutdownCancellationSource.Token); } }
private void OnStatusChanged(object sender, bool started) { if (started) { return; } if (_shutdownCancellationTokenSource.IsCancellationRequested) { lock (_gate) { // RemoteHost has been disabled _remoteClientTask = null; } } else { lock (_gate) { // save last remoteHostClient s_lastRemoteClientTask = _remoteClientTask; // save NoOpRemoteHostClient to remoteClient so that all RemoteHost call becomes // No Op. this basically have same effect as disabling all RemoteHost features _remoteClientTask = Task.FromResult <RemoteHostClient>(new RemoteHostClient.NoOpClient(_workspace)); } // s_lastRemoteClientTask info should be saved in the dump // report NFW when connection is closed unless it is proper shutdown WatsonReporter.Report(new Exception("Connection to remote host closed")); RemoteHostCrashInfoBar.ShowInfoBar(_workspace); } }
protected override void ApplyDocumentTextChanged(DocumentId documentId, SourceText text) { var document = CurrentSolution.GetDocument(documentId); if (document != null) { if (_openedDocs.Values.Contains(documentId) || IsDocumentOpen(documentId)) { var textBuffer = _threadingContext.JoinableTaskFactory.Run(async() => { var sourceText = await document.GetTextAsync().ConfigureAwait(false); var textContainer = sourceText.Container; return(textContainer.TryGetTextBuffer()); }); if (textBuffer == null) { WatsonReporter.Report("Text buffer is missing for opened Live Share document.", new LiveShareTextBufferMissingException()); return; } UpdateText(textBuffer, text); } else { // The edits would get sent by the co-authoring service to the owner. // The invisible editor saves the file on being disposed, which should get reflected on the owner's side. using (var invisibleEditor = new InvisibleEditor(_serviceProvider, document.FilePath, hierarchyOpt: null, needsSave: true, needsUndoDisabled: false)) { UpdateText(invisibleEditor.TextBuffer, text); } } } }
private static bool ExpectedCultureIssue(Exception ex) { // report exception WatsonReporter.Report(ex); // ignore expected exception return(ex is ArgumentOutOfRangeException || ex is CultureNotFoundException); }
private void TrackBulkFileOperations() { // we will pause whatever ambient work loads we have that are tied to IGlobalOperationNotificationService // such as solution crawler, pre-emptive remote host synchronization and etc. any background work users didn't // explicitly asked for. // // this should give all resources to BulkFileOperation. we do same for things like build, // debugging, wait dialog and etc. BulkFileOperation is used for things like git branch switching and etc. var globalNotificationService = _workspace.Services.GetService <IGlobalOperationNotificationService>(); // BulkFileOperation can't have nested events. there will be ever only 1 events (Begin/End) // so we only need simple tracking. object gate = new object(); GlobalOperationRegistration localRegistration = null; BulkFileOperation.End += (s, a) => { StopBulkFileOperationNotification(); }; BulkFileOperation.Begin += (s, a) => { StartBulkFileOperationNotification(); }; void StartBulkFileOperationNotification() { lock (gate) { // this shouldn't happen, but we are using external component // so guarding us from them if (localRegistration != null) { WatsonReporter.Report(new Exception("BulkFileOperation already exist")); return; } localRegistration = globalNotificationService.Start("BulkFileOperation"); } } void StopBulkFileOperationNotification() { lock (gate) { // this can happen if BulkFileOperation was already in the middle // of running. to make things simpler, decide to not use IsInProgress // which we need to worry about race case. if (localRegistration == null) { return; } localRegistration.Dispose(); localRegistration = null; } } }
public static void ReportServiceHubNFW(this Exception exception, string message) { if (exception == null) { return; } WatsonReporter.Report(message, exception, ReportDetailServiceHubLogs); }
private void OnStatusChanged(object sender, bool started) { if (started) { return; } if (_shutdownCancellationTokenSource.IsCancellationRequested) { lock (_gate) { // RemoteHost has been disabled _remoteClientTask = null; } } else { lock (_gate) { // save last remoteHostClient s_lastRemoteClientTask = _remoteClientTask; // save NoOpRemoteHostClient to remoteClient so that all RemoteHost call becomes // No Op. this basically have same effect as disabling all RemoteHost features _remoteClientTask = Task.FromResult <RemoteHostClient>(new RemoteHostClient.NoOpClient(_workspace)); } // s_lastRemoteClientTask info should be saved in the dump // report NFW when connection is closed unless it is proper shutdown WatsonReporter.Report(new Exception("Connection to remote host closed")); // use info bar to show warning to users var infoBarUIs = new List <InfoBarUI>(); infoBarUIs.Add( new InfoBarUI(ServicesVSResources.Learn_more, InfoBarUI.UIKind.HyperLink, () => BrowserHelper.StartBrowser(new Uri(OOPKilledMoreInfoLink)), closeAfterAction: false)); var allowRestarting = _workspace.Options.GetOption(RemoteHostOptions.RestartRemoteHostAllowed); if (allowRestarting) { // this is hidden restart option. by default, user can't restart remote host that got killed // by users infoBarUIs.Add( new InfoBarUI("Restart external process", InfoBarUI.UIKind.Button, () => { // start off new remote host var unused = RequestNewRemoteHostAsync(CancellationToken.None); }, closeAfterAction: true)); } _workspace.Services.GetService <IErrorReportingService>().ShowGlobalErrorInfo( ServicesVSResources.Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio, infoBarUIs.ToArray()); } }
public void LogException(object source, Exception exception) { var name = source.GetType().Name; ActivityLog.LogError(name, ToLogFormat(exception)); if (ShouldReportCrashDumps(source)) { WatsonReporter.Report(name, exception); } }
private static bool ReportNonIOException(Exception ex) { // IOException is expected. log other exceptions if (!(ex is IOException)) { WatsonReporter.Report(ex); } // catch all exception. not worth crashing VS. return(true); }
private static async Task <Stream> RequestServiceAsync( HubClient client, string serviceName, HostGroup hostGroup, TimeSpan timeout, CancellationToken cancellationToken = default(CancellationToken)) { const int max_retry = 10; const int retry_delayInMS = 50; Exception lastException = null; var descriptor = new ServiceDescriptor(serviceName) { HostGroup = hostGroup }; // call to get service can fail due to this bug - devdiv#288961 or more. // until root cause is fixed, we decide to have retry rather than fail right away for (var i = 0; i < max_retry; i++) { try { return(await RequestServiceAsync(client, descriptor, timeout, cancellationToken).ConfigureAwait(false)); } catch (RemoteInvocationException ex) { // save info only if it failed with different issue than before. if (lastException?.Message != ex.Message) { // RequestServiceAsync should never fail unless service itself is actually broken. // So far, we catched multiple issues from this NFW. so we will keep this NFW. WatsonReporter.Report("RequestServiceAsync Failed", ex, ReportDetailInfo); lastException = ex; } } // wait for retry_delayInMS before next try await Task.Delay(retry_delayInMS, cancellationToken).ConfigureAwait(false); } // crash right away to get better dump. otherwise, we will get dump from async exception // which most likely lost all valuable data FatalError.ReportUnlessCanceled(lastException); GC.KeepAlive(lastException); // unreachable throw ExceptionUtilities.Unreachable; }
private bool CanHandle(string errorId) { // make sure we have error id, otherwise, we simple don't support // this error if (errorId == null) { // record NFW to see who violates contract. WatsonReporter.Report(new Exception("errorId is null")); return(false); } // we accept all compiler diagnostics if (errorId.StartsWith(_errorCodePrefix)) { return(true); } return(_diagnosticProvider.SupportedDiagnosticId(_projectId, errorId)); }
private void ReportExtraInfoAsNFW(Exception ex) { WatsonReporter.Report("RemoteHost Failed", ex, u => { try { // we will record dumps for all service hub processes foreach (var p in Process.GetProcessesByName("ServiceHub.RoslynCodeAnalysisService32")) { // include all remote host processes u.AddProcessDump(p.Id); } // include all service hub logs as well var logPath = Path.Combine(Path.GetTempPath(), "servicehub", "logs"); if (Directory.Exists(logPath)) { // attach all log files that are modified less than 1 day before. var now = DateTime.UtcNow; var oneDay = TimeSpan.FromDays(1); foreach (var file in Directory.EnumerateFiles(logPath, "*.log")) { var lastWrite = File.GetLastWriteTimeUtc(file); if (now - lastWrite > oneDay) { continue; } u.AddFile(file); } } } catch { // ignore issue } // 0 means send watson return(0); }); }
public static void ReportNonFatalWatsonWithServiceHubLogs(Exception ex, string message) { WatsonReporter.Report(message, ex, AddServiceHubLogFiles, WatsonSeverity.Critical); }