private void HandleError(Exception ex) { lock (this) { // Per prima cosa occorre notificare l'utente che si è verificato un errore. // Poi decidiamo se siamo in condizione di recuperarlo. // In sostanza si possono verificare le seguenti eccezioni: // 1. User login exception: possiamo gestirla mostrando all'utente una schermata di login dopo aver inibito tutti i thread. // 2. Network Error: possiamo gestirla fermando tutti i thread e eseguendo controlli periodici con un bgworker che verifica la connetività di rete // 3. Eccezione non gestibile: qualcosa di molto brutto è accaduto e non sappiamo che farcene. Logghiamola su un logger e chiudiamo la baracca. Logger.LogError(ex); _mainWindow.NotifyError(ex.Message); if (ex is StartupException) { var res = MessageBox.Show("La sincronizzazione iniziale non è andata a buon fine, errore: " + ex.InnerException.Message + ". Vuoi ritentare?", "Sincronizzazione fallita", MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) Startup(); } else if (ex is UserLogoutException) { var res = MessageBox.Show("Il logout non ha avuto successo, si vuole comunque procedere con l'eliminazione delle credenziali locali?","Logout remoto fallito", MessageBoxButton.YesNo); if (res == MessageBoxResult.Yes) UserCredentials.Reset(); } else if (ex is NetworkException || ex is System.Net.Sockets.SocketException) { // Se non è stata ancora presa alcuna decisione per questo genere di errore, eseguiamo la gestione if (!_netErrorHandled) { _netErrorHandled = true; ApplicationState.Instance.Pause(); _networkMonitor = new BackgroundWorker(); _networkMonitor.DoWork += (object sender, DoWorkEventArgs args) => { UserCredentials cred = UserCredentials.Instance; while (true) { try { using (TcpClient c = new TcpClient()) { c.Connect(cred.Host, cred.Port); } // Ok, finisce il worker break; } catch (Exception e) { // Do nothing, la rete ancora giù continue; // Opzionale } } }; _networkMonitor.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs args) => { // A connessione ristabilita, riattiva tutti i thread ApplicationState.Instance.Resume(); _netErrorHandled = false; // Richioso ma utile. }; _networkMonitor.RunWorkerAsync(); } //Altrimenti qualcuno sta già gestendo l'eccezione. } else if (ex is UserLoginException) { ApplicationState.Instance.Pause(); LoginWindow lw = new LoginWindow(); bool? loginok = lw.ShowDialog(); if (loginok == null || loginok == false) { // Il login non è andato a buon fine Shutdown(RETURN_VALUES.LOGIN_REFUSED); } else { // Il login è andato a buoin fine, facciamo ripartire tutto ApplicationState.Instance.Resume(); } } else if (ex is FileInUseException) { // In questo caso decido di ignorare l'errore che continuerà a presentarsi finchè l'utente // modifica attivamente il file. } else { Shutdown(RETURN_VALUES.GENERAL_ERROR); } } }
public void RequireLogin() { Logger.LogInfo("Richiesto il login dell'utente."); LoginWindow _loginWindow = new LoginWindow(); // Mostrare la UI di login _loginWindow.SetWaiting(false, "Si prega di eseguire il login"); _loginWindow.ShowDialog(); Startup(); }