diff --git a/internal/frontend/grpc/service_cert.go b/internal/frontend/grpc/service_cert.go index c900d06a..b78ec16f 100644 --- a/internal/frontend/grpc/service_cert.go +++ b/internal/frontend/grpc/service_cert.go @@ -30,6 +30,8 @@ import ( ) func (s *Service) IsTLSCertificateInstalled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Info("IsTLSCertificateInstalled") cert, _ := s.bridge.GetBridgeTLSCert() diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go index 92534309..51463b6a 100644 --- a/internal/frontend/grpc/service_methods.go +++ b/internal/frontend/grpc/service_methods.go @@ -45,6 +45,7 @@ import ( // CheckTokens implements the CheckToken gRPC service call. func (s *Service) CheckTokens(_ context.Context, clientConfigPath *wrapperspb.StringValue) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("CheckTokens") path := clientConfigPath.Value @@ -63,6 +64,7 @@ func (s *Service) CheckTokens(_ context.Context, clientConfigPath *wrapperspb.St } func (s *Service) AddLogEntry(_ context.Context, request *AddLogEntryRequest) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) entry := s.log if len(request.Package) > 0 { @@ -91,6 +93,7 @@ func (s *Service) AddLogEntry(_ context.Context, request *AddLogEntryRequest) (* // GuiReady implement the GuiReady gRPC service call. func (s *Service) GuiReady(_ context.Context, _ *emptypb.Empty) (*GuiReadyResponse, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("GuiReady") s.initializationDone.Do(s.initializing.Done) @@ -105,6 +108,7 @@ func (s *Service) GuiReady(_ context.Context, _ *emptypb.Empty) (*GuiReadyRespon // Quit implement the Quit gRPC service call. func (s *Service) Quit(_ context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("Quit") return &emptypb.Empty{}, s.quit() } @@ -134,6 +138,7 @@ func (s *Service) quit() error { // Restart implement the Restart gRPC service call. func (s *Service) Restart(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("Restart") s.restarter.Set(true, false) @@ -141,12 +146,14 @@ func (s *Service) Restart(ctx context.Context, empty *emptypb.Empty) (*emptypb.E } func (s *Service) ShowOnStartup(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("ShowOnStartup") return wrapperspb.Bool(s.showOnStartup), nil } func (s *Service) SetIsAutostartOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("show", isOn.Value).Debug("SetIsAutostartOn") defer func() { _ = s.SendEvent(NewToggleAutostartFinishedEvent()) }() @@ -167,12 +174,14 @@ func (s *Service) SetIsAutostartOn(_ context.Context, isOn *wrapperspb.BoolValue } func (s *Service) IsAutostartOn(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("IsAutostartOn") return wrapperspb.Bool(s.bridge.GetAutostart()), nil } func (s *Service) SetIsBetaEnabled(_ context.Context, isEnabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("isEnabled", isEnabled.Value).Debug("SetIsBetaEnabled") channel := updater.StableChannel @@ -189,12 +198,14 @@ func (s *Service) SetIsBetaEnabled(_ context.Context, isEnabled *wrapperspb.Bool } func (s *Service) IsBetaEnabled(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("IsBetaEnabled") return wrapperspb.Bool(s.bridge.GetUpdateChannel() == updater.EarlyChannel), nil } func (s *Service) SetIsAllMailVisible(_ context.Context, isVisible *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("isVisible", isVisible.Value).Debug("SetIsAllMailVisible") if err := s.bridge.SetShowAllMail(isVisible.Value); err != nil { @@ -206,12 +217,14 @@ func (s *Service) SetIsAllMailVisible(_ context.Context, isVisible *wrapperspb.B } func (s *Service) IsAllMailVisible(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("IsAllMailVisible") return wrapperspb.Bool(s.bridge.GetShowAllMail()), nil } func (s *Service) SetIsTelemetryDisabled(_ context.Context, isDisabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("isEnabled", isDisabled.Value).Debug("SetIsTelemetryDisabled") if err := s.bridge.SetTelemetryDisabled(isDisabled.Value); err != nil { @@ -223,12 +236,14 @@ func (s *Service) SetIsTelemetryDisabled(_ context.Context, isDisabled *wrappers } func (s *Service) IsTelemetryDisabled(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("IsTelemetryDisabled") return wrapperspb.Bool(s.bridge.GetTelemetryDisabled()), nil } func (s *Service) GoOs(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("GoOs") // TO-DO We can probably get rid of this and use QSysInfo::product name return wrapperspb.String(runtime.GOOS), nil @@ -246,12 +261,14 @@ func (s *Service) TriggerReset(_ context.Context, _ *emptypb.Empty) (*emptypb.Em } func (s *Service) Version(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("Version") return wrapperspb.String(s.bridge.GetCurrentVersion().Original()), nil } func (s *Service) LogsPath(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("LogsPath") path, err := s.bridge.GetLogsPath() @@ -263,30 +280,40 @@ func (s *Service) LogsPath(_ context.Context, _ *emptypb.Empty) (*wrapperspb.Str } func (s *Service) LicensePath(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("LicensePath") return wrapperspb.String(s.bridge.GetLicenseFilePath()), nil } func (s *Service) DependencyLicensesLink(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) return wrapperspb.String(s.bridge.GetDependencyLicensesLink()), nil } func (s *Service) ReleaseNotesPageLink(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { s.latestLock.RLock() - defer s.latestLock.RUnlock() + defer func() { + async.HandlePanic(s.panicHandler) + s.latestLock.RUnlock() + }() return wrapperspb.String(s.latest.ReleaseNotesPage), nil } func (s *Service) LandingPageLink(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { s.latestLock.RLock() - defer s.latestLock.RUnlock() + defer func() { + async.HandlePanic(s.panicHandler) + s.latestLock.RUnlock() + }() return wrapperspb.String(s.latest.LandingPage), nil } func (s *Service) SetColorSchemeName(_ context.Context, name *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("ColorSchemeName", name.Value).Debug("SetColorSchemeName") if !theme.IsAvailable(theme.Theme(name.Value)) { @@ -303,6 +330,8 @@ func (s *Service) SetColorSchemeName(_ context.Context, name *wrapperspb.StringV } func (s *Service) ColorSchemeName(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("ColorSchemeName") current := s.bridge.GetColorScheme() @@ -318,6 +347,8 @@ func (s *Service) ColorSchemeName(_ context.Context, _ *emptypb.Empty) (*wrapper } func (s *Service) CurrentEmailClient(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("CurrentEmailClient") return wrapperspb.String(s.bridge.GetCurrentUserAgent()), nil @@ -361,6 +392,8 @@ func (s *Service) ReportBug(_ context.Context, report *ReportBugRequest) (*empty } func (s *Service) ForceLauncher(_ context.Context, launcher *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("launcher", launcher.Value).Debug("ForceLauncher") s.restarter.Override(launcher.Value) @@ -369,6 +402,8 @@ func (s *Service) ForceLauncher(_ context.Context, launcher *wrapperspb.StringVa } func (s *Service) SetMainExecutable(_ context.Context, exe *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("executable", exe.Value).Debug("SetMainExecutable") s.restarter.AddFlags("--wait", exe.Value) @@ -590,6 +625,8 @@ func (s *Service) InstallUpdate(_ context.Context, _ *emptypb.Empty) (*emptypb.E } func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("isOn", isOn.Value).Debug("SetIsAutomaticUpdateOn") if currentlyOn := s.bridge.GetAutoUpdate(); currentlyOn == isOn.Value { @@ -605,12 +642,16 @@ func (s *Service) SetIsAutomaticUpdateOn(_ context.Context, isOn *wrapperspb.Boo } func (s *Service) IsAutomaticUpdateOn(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("IsAutomaticUpdateOn") return wrapperspb.Bool(s.bridge.GetAutoUpdate()), nil } func (s *Service) DiskCachePath(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("DiskCachePath") return wrapperspb.String(s.bridge.GetGluonCacheDir()), nil @@ -648,6 +689,8 @@ func (s *Service) SetDiskCachePath(_ context.Context, newPath *wrapperspb.String } func (s *Service) SetIsDoHEnabled(_ context.Context, isEnabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("isEnabled", isEnabled.Value).Debug("SetIsDohEnabled") if err := s.bridge.SetProxyAllowed(isEnabled.Value); err != nil { @@ -659,12 +702,16 @@ func (s *Service) SetIsDoHEnabled(_ context.Context, isEnabled *wrapperspb.BoolV } func (s *Service) IsDoHEnabled(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("IsDohEnabled") return wrapperspb.Bool(s.bridge.GetProxyAllowed()), nil } func (s *Service) MailServerSettings(_ context.Context, _ *emptypb.Empty) (*ImapSmtpSettings, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("ConnectionMode") return &ImapSmtpSettings{ @@ -728,24 +775,32 @@ func (s *Service) SetMailServerSettings(_ context.Context, settings *ImapSmtpSet } func (s *Service) Hostname(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("Hostname") return wrapperspb.String(constants.Host), nil } func (s *Service) IsPortFree(_ context.Context, port *wrapperspb.Int32Value) (*wrapperspb.BoolValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("IsPortFree") return wrapperspb.Bool(ports.IsPortFree(int(port.Value))), nil } func (s *Service) AvailableKeychains(_ context.Context, _ *emptypb.Empty) (*AvailableKeychainsResponse, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("AvailableKeychains") return &AvailableKeychainsResponse{Keychains: s.bridge.GetHelpersNames()}, nil } func (s *Service) SetCurrentKeychain(ctx context.Context, keychain *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) + s.log.WithField("keychain", keychain.Value).Debug("SetCurrentKeyChain") // we do not check validity. defer func() { _, _ = s.Restart(ctx, &emptypb.Empty{}) }() @@ -770,6 +825,8 @@ func (s *Service) SetCurrentKeychain(ctx context.Context, keychain *wrapperspb.S } func (s *Service) CurrentKeychain(_ context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { + defer async.HandlePanic(s.panicHandler) + s.log.Debug("CurrentKeychain") helper, err := s.bridge.GetKeychainApp() diff --git a/internal/frontend/grpc/service_telemetry.go b/internal/frontend/grpc/service_telemetry.go index c4bfa9d2..d81107e9 100644 --- a/internal/frontend/grpc/service_telemetry.go +++ b/internal/frontend/grpc/service_telemetry.go @@ -20,21 +20,25 @@ package grpc import ( "context" + "github.com/ProtonMail/gluon/async" "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/wrapperspb" ) func (s *Service) ReportBugClicked(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.bridge.ReportBugClicked() return &emptypb.Empty{}, nil } func (s *Service) AutoconfigClicked(_ context.Context, client *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.bridge.AutoconfigUsed(client.Value) return &emptypb.Empty{}, nil } func (s *Service) ExternalLinkClicked(_ context.Context, article *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.bridge.ExternalLinkClicked(article.Value) return &emptypb.Empty{}, nil } diff --git a/internal/frontend/grpc/service_user.go b/internal/frontend/grpc/service_user.go index d09c2e85..c332b958 100644 --- a/internal/frontend/grpc/service_user.go +++ b/internal/frontend/grpc/service_user.go @@ -29,6 +29,7 @@ import ( ) func (s *Service) GetUserList(_ context.Context, _ *emptypb.Empty) (*UserListResponse, error) { + defer async.HandlePanic(s.panicHandler) s.log.Debug("GetUserList") userIDs := s.bridge.GetUserIDs() @@ -52,6 +53,7 @@ func (s *Service) GetUserList(_ context.Context, _ *emptypb.Empty) (*UserListRes } func (s *Service) GetUser(_ context.Context, userID *wrapperspb.StringValue) (*User, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("userID", userID).Debug("GetUser") user, err := s.bridge.GetUserInfo(userID.Value) @@ -63,6 +65,7 @@ func (s *Service) GetUser(_ context.Context, userID *wrapperspb.StringValue) (*U } func (s *Service) SetUserSplitMode(_ context.Context, splitMode *UserSplitModeRequest) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("UserID", splitMode.UserID).WithField("Active", splitMode.Active).Debug("SetUserSplitMode") user, err := s.bridge.GetUserInfo(splitMode.UserID) @@ -97,6 +100,7 @@ func (s *Service) SetUserSplitMode(_ context.Context, splitMode *UserSplitModeRe } func (s *Service) SendBadEventUserFeedback(_ context.Context, feedback *UserBadEventFeedbackRequest) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) l := s.log.WithField("UserID", feedback.UserID).WithField("doResync", feedback.DoResync) l.Debug("SendBadEventUserFeedback") @@ -115,6 +119,7 @@ func (s *Service) SendBadEventUserFeedback(_ context.Context, feedback *UserBadE } func (s *Service) LogoutUser(_ context.Context, userID *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("UserID", userID.Value).Debug("LogoutUser") if _, err := s.bridge.GetUserInfo(userID.Value); err != nil { @@ -133,6 +138,7 @@ func (s *Service) LogoutUser(_ context.Context, userID *wrapperspb.StringValue) } func (s *Service) RemoveUser(_ context.Context, userID *wrapperspb.StringValue) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("UserID", userID.Value).Debug("RemoveUser") go func() { @@ -148,6 +154,7 @@ func (s *Service) RemoveUser(_ context.Context, userID *wrapperspb.StringValue) } func (s *Service) ConfigureUserAppleMail(ctx context.Context, request *ConfigureAppleMailRequest) (*emptypb.Empty, error) { + defer async.HandlePanic(s.panicHandler) s.log.WithField("UserID", request.UserID).WithField("Address", request.Address).Debug("ConfigureUserAppleMail") sslWasEnabled := s.bridge.GetSMTPSSL()