From 73304067520be98e506a137b1c013f6af3cb63a7 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 4 Apr 2023 15:27:03 +0200 Subject: [PATCH] fix(GODT-2500): Recover in deferred function. --- Makefile | 6 ++- cmd/launcher/main.go | 3 +- go.mod | 4 +- go.sum | 8 ++-- internal/app/app.go | 3 +- internal/app/frontend.go | 5 ++- internal/app/singleinstance.go | 2 +- internal/bridge/mocks.go | 2 +- internal/bridge/mocks/async_mocks.go | 10 ++--- internal/crash/handler.go | 14 +++--- internal/crash/handler_test.go | 53 ++++++++++++----------- internal/frontend/cli/frontend.go | 13 +++++- internal/frontend/grpc/service.go | 16 +++---- internal/frontend/grpc/service_methods.go | 25 ++++++----- internal/frontend/grpc/service_stream.go | 3 +- internal/frontend/grpc/service_user.go | 7 +-- internal/frontend/grpc/types.go | 4 -- internal/user/sync.go | 10 ++--- 18 files changed, 103 insertions(+), 85 deletions(-) diff --git a/Makefile b/Makefile index b5715507..4778a393 100644 --- a/Makefile +++ b/Makefile @@ -325,7 +325,11 @@ run-nogui: build-nogui clean-vendor gofiles PROTONMAIL_ENV=dev ./${LAUNCHER_EXE} ${RUN_FLAGS} -c run-debug: - dlv debug ./cmd/Desktop-Bridge/main.go -- -l=debug + dlv debug \ + --build-flags "-ldflags '-X github.com/ProtonMail/proton-bridge/v3/internal/constants.Version=3.1.0+git'" \ + ./cmd/Desktop-Bridge/main.go \ + -- \ + -n -l=trace ifeq "${TARGET_OS}" "windows" EXE_SUFFIX=.exe diff --git a/cmd/launcher/main.go b/cmd/launcher/main.go index a6c15889..8fd75c47 100644 --- a/cmd/launcher/main.go +++ b/cmd/launcher/main.go @@ -25,6 +25,7 @@ import ( "time" "github.com/Masterminds/semver/v3" + "github.com/ProtonMail/gluon/async" "github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/crash" @@ -62,7 +63,7 @@ func main() { //nolint:funlen reporter := sentry.NewReporter(appName, useragent.New()) crashHandler := crash.NewHandler(reporter.ReportException) - defer crashHandler.HandlePanic() + defer async.HandlePanic(crashHandler) locationsProvider, err := locations.NewDefaultProvider(filepath.Join(constants.VendorName, constants.ConfigName)) if err != nil { diff --git a/go.mod b/go.mod index 66927c0d..bff763cb 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.18 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.2.0 - github.com/ProtonMail/gluon v0.15.1-0.20230331095629-e23a7a1be2a8 + github.com/ProtonMail/gluon v0.15.1-0.20230405065656-e75e877aede1 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a - github.com/ProtonMail/go-proton-api v0.4.1-0.20230331115846-7ba084061eaa + github.com/ProtonMail/go-proton-api v0.4.1-0.20230405072218-d91d6600a52e github.com/ProtonMail/gopenpgp/v2 v2.5.2 github.com/PuerkitoBio/goquery v1.8.1 github.com/abiosoft/ishell v2.0.0+incompatible diff --git a/go.sum b/go.sum index 1466ca35..c0fd0c0b 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.15.1-0.20230331095629-e23a7a1be2a8 h1:USMR8imbxkP4Ailch4ceV3hCZTaANMIGHhb5rpZFYn4= -github.com/ProtonMail/gluon v0.15.1-0.20230331095629-e23a7a1be2a8/go.mod h1:yA4hk6CJw0BMo+YL8Y3ckCYs5L20sysu9xseshwY3QI= +github.com/ProtonMail/gluon v0.15.1-0.20230405065656-e75e877aede1 h1:DLz6hm2Sb04dwWzzrXm14wRVzNYSuA0aOjWfnAF3cmw= +github.com/ProtonMail/gluon v0.15.1-0.20230405065656-e75e877aede1/go.mod h1:yA4hk6CJw0BMo+YL8Y3ckCYs5L20sysu9xseshwY3QI= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= @@ -40,8 +40,8 @@ github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 h1:I8IsYA297 github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= github.com/ProtonMail/go-mime v0.0.0-20221031134845-8fd9bc37cf08 h1:dS7r5z4iGS0qCjM7UwWdsEMzQesUQbGcXdSm2/tWboA= github.com/ProtonMail/go-mime v0.0.0-20221031134845-8fd9bc37cf08/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230331115846-7ba084061eaa h1:0JKWkz/gIYf+eky0dCFeBWrjEDLf59lS8HOlXtvn6Nk= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230331115846-7ba084061eaa/go.mod h1:RfpLBcTIhfjOIcBhh7f36LtAOEi0mqPd3t8gyLWmCZM= +github.com/ProtonMail/go-proton-api v0.4.1-0.20230405072218-d91d6600a52e h1:ZCvETTjO4oefRtBFG7jHdYZKKybkEcSkisSsKvSG5og= +github.com/ProtonMail/go-proton-api v0.4.1-0.20230405072218-d91d6600a52e/go.mod h1:tsV8BDWZcrV3oYI7ZhpCozg8NC09Nw48IGZkprgcM7o= github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg= github.com/ProtonMail/go-srp v0.0.5/go.mod h1:06iYHtLXW8vjLtccWj++x3MKy65sIT8yZd7nrJF49rs= github.com/ProtonMail/gopenpgp/v2 v2.5.2 h1:97SjlWNAxXl9P22lgwgrZRshQdiEfAht0g3ZoiA1GCw= diff --git a/internal/app/app.go b/internal/app/app.go index 4cdbd187..3ee0d038 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -28,6 +28,7 @@ import ( "time" "github.com/Masterminds/semver/v3" + "github.com/ProtonMail/gluon/async" "github.com/ProtonMail/proton-bridge/v3/internal/bridge" "github.com/ProtonMail/proton-bridge/v3/internal/constants" "github.com/ProtonMail/proton-bridge/v3/internal/cookies" @@ -379,7 +380,7 @@ func withCrashHandler(restarter *restarter.Restarter, reporter *sentry.Reporter, defer logrus.Debug("Crash handler stopped") crashHandler := crash.NewHandler(crash.ShowErrorNotification(constants.FullAppName)) - defer crashHandler.HandlePanic() + defer async.HandlePanic(crashHandler) // On crash, send crash report to Sentry. crashHandler.AddRecoveryAction(reporter.ReportException) diff --git a/internal/app/frontend.go b/internal/app/frontend.go index 6e1bd8fa..3bf570d2 100644 --- a/internal/app/frontend.go +++ b/internal/app/frontend.go @@ -46,10 +46,11 @@ func runFrontend( switch { case c.Bool(flagCLI): - return bridgeCLI.New(bridge, restarter, eventCh, crashHandler).Loop() + return bridgeCLI.New(bridge, restarter, eventCh, crashHandler, quitCh).Loop() case c.Bool(flagNonInteractive): - select {} + <-quitCh + return nil case c.Bool(flagGRPC): service, err := grpc.NewService(crashHandler, restarter, locations, bridge, eventCh, quitCh, !c.Bool(flagNoWindow), parentPID) diff --git a/internal/app/singleinstance.go b/internal/app/singleinstance.go index 4e6b6dc7..3a11eda1 100644 --- a/internal/app/singleinstance.go +++ b/internal/app/singleinstance.go @@ -40,7 +40,7 @@ func checkSingleInstance(settingPath, lockFilePath string, curVersion *semver.Ve return lock, nil } - logrus.Debug("Failed to create lock file; another instance is running") + logrus.Warn("Failed to create lock file; another instance is running") // We couldn't create the lock file, so another instance is probably running. // Check if it's an older version of the app. diff --git a/internal/bridge/mocks.go b/internal/bridge/mocks.go index 564b94af..6f5c943f 100644 --- a/internal/bridge/mocks.go +++ b/internal/bridge/mocks.go @@ -45,7 +45,7 @@ func NewMocks(tb testing.TB, version, minAuto *semver.Version) *Mocks { mocks.TLSReporter.EXPECT().GetTLSIssueCh().Return(mocks.TLSIssueCh).AnyTimes() // This is called at he end of any go-routine: - mocks.CrashHandler.EXPECT().HandlePanic().AnyTimes() + mocks.CrashHandler.EXPECT().HandlePanic(gomock.Any()).AnyTimes() return mocks } diff --git a/internal/bridge/mocks/async_mocks.go b/internal/bridge/mocks/async_mocks.go index a528a205..53417df8 100644 --- a/internal/bridge/mocks/async_mocks.go +++ b/internal/bridge/mocks/async_mocks.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ProtonMail/proton-bridge/v3/internal/async (interfaces: PanicHandler) +// Source: github.com/ProtonMail/gluon/async (interfaces: PanicHandler) // Package mocks is a generated GoMock package. package mocks @@ -34,13 +34,13 @@ func (m *MockPanicHandler) EXPECT() *MockPanicHandlerMockRecorder { } // HandlePanic mocks base method. -func (m *MockPanicHandler) HandlePanic() { +func (m *MockPanicHandler) HandlePanic(arg0 interface{}) { m.ctrl.T.Helper() - m.ctrl.Call(m, "HandlePanic") + m.ctrl.Call(m, "HandlePanic", arg0) } // HandlePanic indicates an expected call of HandlePanic. -func (mr *MockPanicHandlerMockRecorder) HandlePanic() *gomock.Call { +func (mr *MockPanicHandlerMockRecorder) HandlePanic(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic), arg0) } diff --git a/internal/crash/handler.go b/internal/crash/handler.go index b767875f..1542797c 100644 --- a/internal/crash/handler.go +++ b/internal/crash/handler.go @@ -38,14 +38,16 @@ func (h *Handler) AddRecoveryAction(action RecoveryAction) *Handler { return h } -func (h *Handler) HandlePanic() { +func (h *Handler) HandlePanic(r interface{}) { sentry.SkipDuringUnwind() - if r := recover(); r != nil { - for _, action := range h.actions { - if err := action(r); err != nil { - logrus.WithError(err).Error("Failed to execute recovery action") - } + if r == nil { + return + } + + for _, action := range h.actions { + if err := action(r); err != nil { + logrus.WithError(err).Error("Failed to execute recovery action") } } } diff --git a/internal/crash/handler_test.go b/internal/crash/handler_test.go index b7084125..a71f9884 100644 --- a/internal/crash/handler_test.go +++ b/internal/crash/handler_test.go @@ -21,38 +21,41 @@ import ( "fmt" "testing" + "github.com/ProtonMail/gluon/async" "github.com/stretchr/testify/assert" ) func TestHandler(t *testing.T) { - var s string + assert.NotPanics(t, func() { + var s string - h := NewHandler( - func(r interface{}) error { - s += fmt.Sprintf("1: %v\n", r) - return nil - }, - func(r interface{}) error { - s += fmt.Sprintf("2: %v\n", r) - return nil - }, - ) + h := NewHandler( + func(r interface{}) error { + s += fmt.Sprintf("1: %v\n", r) + return nil + }, + func(r interface{}) error { + s += fmt.Sprintf("2: %v\n", r) + return nil + }, + ) - h. - AddRecoveryAction(func(r interface{}) error { - s += fmt.Sprintf("3: %v\n", r) - return nil - }). - AddRecoveryAction(func(r interface{}) error { - s += fmt.Sprintf("4: %v\n", r) - return nil - }) + h. + AddRecoveryAction(func(r interface{}) error { + s += fmt.Sprintf("3: %v\n", r) + return nil + }). + AddRecoveryAction(func(r interface{}) error { + s += fmt.Sprintf("4: %v\n", r) + return nil + }) - defer func() { - assert.Equal(t, "1: thing\n2: thing\n3: thing\n4: thing\n", s) - }() + defer func() { + assert.Equal(t, "1: thing\n2: thing\n3: thing\n4: thing\n", s) + }() - defer h.HandlePanic() + defer async.HandlePanic(h) - panic("thing") + panic("thing") + }) } diff --git a/internal/frontend/cli/frontend.go b/internal/frontend/cli/frontend.go index d71f053a..bd08cc00 100644 --- a/internal/frontend/cli/frontend.go +++ b/internal/frontend/cli/frontend.go @@ -45,7 +45,13 @@ type frontendCLI struct { } // New returns a new CLI frontend configured with the given options. -func New(bridge *bridge.Bridge, restarter *restarter.Restarter, eventCh <-chan events.Event, panicHandler async.PanicHandler) *frontendCLI { //nolint:revive +func New( + bridge *bridge.Bridge, + restarter *restarter.Restarter, + eventCh <-chan events.Event, + panicHandler async.PanicHandler, + quitCh <-chan struct{}, +) *frontendCLI { //nolint:revive fe := &frontendCLI{ Shell: ishell.New(), bridge: bridge, @@ -285,6 +291,11 @@ func New(bridge *bridge.Bridge, restarter *restarter.Restarter, eventCh <-chan e go fe.watchEvents(eventCh) + go func() { + <-quitCh + fe.Close() + }() + return fe } diff --git a/internal/frontend/grpc/service.go b/internal/frontend/grpc/service.go index e22d66ad..ef9f8f18 100644 --- a/internal/frontend/grpc/service.go +++ b/internal/frontend/grpc/service.go @@ -70,7 +70,7 @@ type Service struct { // nolint:structcheck eventQueue []*StreamEvent eventQueueMutex sync.Mutex - panicHandler CrashHandler + panicHandler async.PanicHandler restarter Restarter bridge *bridge.Bridge eventCh <-chan events.Event @@ -97,7 +97,7 @@ type Service struct { // nolint:structcheck // NewService returns a new instance of the service. func NewService( - panicHandler CrashHandler, + panicHandler async.PanicHandler, restarter Restarter, locations service.Locator, bridge *bridge.Bridge, @@ -192,10 +192,6 @@ func NewService( return s, nil } -func (s *Service) handlePanic() { - async.HandlePanic(s.panicHandler) -} - func (s *Service) initAutostart() { s.firstTimeAutostart.Do(func() { shouldAutostartBeOn := s.bridge.GetAutostart() @@ -213,13 +209,13 @@ func (s *Service) Loop() error { s.log.Info("Not monitoring parent PID") } else { go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) s.monitorParentPID() }() } go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) s.watchEvents() }() @@ -229,7 +225,7 @@ func (s *Service) Loop() error { defer close(doneCh) go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) select { case <-s.quitCh: @@ -577,7 +573,7 @@ func (s *Service) monitorParentPID() { s.log.Info("Parent process does not exist anymore. Initiating shutdown") // quit will write to the parentPIDDoneCh, so we launch a goroutine. go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) if err := s.quit(); err != nil { logrus.WithError(err).Error("Error on quit") diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go index be5d7276..0a4321ec 100644 --- a/internal/frontend/grpc/service_methods.go +++ b/internal/frontend/grpc/service_methods.go @@ -26,6 +26,7 @@ import ( "runtime" "github.com/Masterminds/semver/v3" + "github.com/ProtonMail/gluon/async" "github.com/ProtonMail/go-proton-api" "github.com/ProtonMail/proton-bridge/v3/internal/bridge" "github.com/ProtonMail/proton-bridge/v3/internal/constants" @@ -114,7 +115,7 @@ func (s *Service) Quit(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empt func (s *Service) quit() error { // Windows is notably slow at Quitting. We do it in a goroutine to speed things up a bit. go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) if s.parentPID >= 0 { s.parentPIDDoneCh <- struct{}{} @@ -223,7 +224,7 @@ func (s *Service) TriggerReset(ctx context.Context, _ *emptypb.Empty) (*emptypb. s.log.Debug("TriggerReset") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) s.triggerReset() }() @@ -319,7 +320,7 @@ func (s *Service) ReportBug(ctx context.Context, report *ReportBugRequest) (*emp }).Debug("ReportBug") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) defer func() { _ = s.SendEvent(NewReportBugFinishedEvent()) }() @@ -348,7 +349,7 @@ func (s *Service) ExportTLSCertificates(_ context.Context, folderPath *wrappersp s.log.WithField("folderPath", folderPath).Info("ExportTLSCertificates") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) cert, key := s.bridge.GetBridgeTLSCert() @@ -384,7 +385,7 @@ func (s *Service) Login(ctx context.Context, login *LoginRequest) (*emptypb.Empt s.log.WithField("username", login.Username).Debug("Login") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) password, err := base64Decode(login.Password) if err != nil { @@ -440,7 +441,7 @@ func (s *Service) Login2FA(ctx context.Context, login *LoginRequest) (*emptypb.E s.log.WithField("username", login.Username).Debug("Login2FA") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) if s.auth.UID == "" || s.authClient == nil { s.log.Errorf("Login 2FA: authethication incomplete %s %p", s.auth.UID, s.authClient) @@ -485,7 +486,7 @@ func (s *Service) Login2Passwords(ctx context.Context, login *LoginRequest) (*em s.log.WithField("username", login.Username).Debug("Login2Passwords") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) password, err := base64Decode(login.Password) if err != nil { @@ -507,7 +508,7 @@ func (s *Service) LoginAbort(ctx context.Context, loginAbort *LoginAbortRequest) s.log.WithField("username", loginAbort.Username).Debug("LoginAbort") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) s.loginAbort() }() @@ -519,7 +520,7 @@ func (s *Service) CheckUpdate(context.Context, *emptypb.Empty) (*emptypb.Empty, s.log.Debug("CheckUpdate") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) updateCh, done := s.bridge.GetEvents( events.UpdateAvailable{}, @@ -551,7 +552,7 @@ func (s *Service) InstallUpdate(ctx context.Context, _ *emptypb.Empty) (*emptypb s.log.Debug("InstallUpdate") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) safe.RLock(func() { s.bridge.InstallUpdate(s.target) @@ -592,7 +593,7 @@ func (s *Service) SetDiskCachePath(ctx context.Context, newPath *wrapperspb.Stri s.log.WithField("path", newPath.Value).Debug("setDiskCachePath") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) defer func() { _ = s.SendEvent(NewDiskCachePathChangeFinishedEvent()) @@ -659,7 +660,7 @@ func (s *Service) SetMailServerSettings(_ context.Context, settings *ImapSmtpSet Debug("SetConnectionMode") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) defer func() { _ = s.SendEvent(NewChangeMailServerSettingsFinishedEvent()) }() diff --git a/internal/frontend/grpc/service_stream.go b/internal/frontend/grpc/service_stream.go index 4b5462da..a7491dae 100644 --- a/internal/frontend/grpc/service_stream.go +++ b/internal/frontend/grpc/service_stream.go @@ -20,6 +20,7 @@ package grpc import ( "context" + "github.com/ProtonMail/gluon/async" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -49,7 +50,7 @@ func (s *Service) RunEventStream(request *EventStreamRequest, server Bridge_RunE // if events occurred before streaming started, they've been queued. Now that the stream channel is available // we can flush the queued go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) s.eventQueueMutex.Lock() defer s.eventQueueMutex.Unlock() diff --git a/internal/frontend/grpc/service_user.go b/internal/frontend/grpc/service_user.go index e3290c33..8a72c985 100644 --- a/internal/frontend/grpc/service_user.go +++ b/internal/frontend/grpc/service_user.go @@ -20,6 +20,7 @@ package grpc import ( "context" + "github.com/ProtonMail/gluon/async" "github.com/ProtonMail/proton-bridge/v3/internal/vault" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -70,7 +71,7 @@ func (s *Service) SetUserSplitMode(ctx context.Context, splitMode *UserSplitMode } go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) defer func() { _ = s.SendEvent(NewUserToggleSplitModeFinishedEvent(splitMode.UserID)) }() var targetMode vault.AddressMode @@ -121,7 +122,7 @@ func (s *Service) LogoutUser(ctx context.Context, userID *wrapperspb.StringValue } go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) if err := s.bridge.LogoutUser(context.Background(), userID.Value); err != nil { s.log.WithError(err).Error("Failed to log user out") @@ -135,7 +136,7 @@ func (s *Service) RemoveUser(ctx context.Context, userID *wrapperspb.StringValue s.log.WithField("UserID", userID.Value).Debug("RemoveUser") go func() { - defer s.handlePanic() + defer async.HandlePanic(s.panicHandler) // remove preferences if err := s.bridge.DeleteUser(context.Background(), userID.Value); err != nil { diff --git a/internal/frontend/grpc/types.go b/internal/frontend/grpc/types.go index f92f8b3b..95c51959 100644 --- a/internal/frontend/grpc/types.go +++ b/internal/frontend/grpc/types.go @@ -17,10 +17,6 @@ package grpc -type CrashHandler interface { - HandlePanic() -} - type Restarter interface { Set(restart, crash bool) AddFlags(flags ...string) diff --git a/internal/user/sync.go b/internal/user/sync.go index 6c40cd46..03515645 100644 --- a/internal/user/sync.go +++ b/internal/user/sync.go @@ -370,7 +370,7 @@ func (user *User) syncMessages( errorCh := make(chan error, maxParallelDownloads*4) // Go routine in charge of downloading message metadata - logging.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { + async.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { defer close(downloadCh) const MetadataDataPageSize = 150 @@ -433,7 +433,7 @@ func (user *User) syncMessages( }, logging.Labels{"sync-stage": "meta-data"}) // Goroutine in charge of downloading and building messages in maxBatchSize batches. - logging.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { + async.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { defer close(buildCh) defer close(errorCh) defer func() { @@ -492,7 +492,7 @@ func (user *User) syncMessages( }, logging.Labels{"sync-stage": "download"}) // Goroutine which builds messages after they have been downloaded - logging.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { + async.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { defer close(flushCh) defer func() { logrus.Debugf("sync builder exit") @@ -530,7 +530,7 @@ func (user *User) syncMessages( }, logging.Labels{"sync-stage": "builder"}) // Goroutine which converts the messages into updates and builds a waitable structure for progress tracking. - logging.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { + async.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { defer close(flushUpdateCh) defer func() { logrus.Debugf("sync flush exit") @@ -780,7 +780,7 @@ func (user *User) newAttachmentDownloader(ctx context.Context, client *proton.Cl ctx, cancel := context.WithCancel(ctx) for i := 0; i < workerCount; i++ { workerCh = make(chan attachmentJob) - logging.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { attachmentWorker(ctx, client, workerCh) }, logging.Labels{ + async.GoAnnotated(ctx, user.panicHandler, func(ctx context.Context) { attachmentWorker(ctx, client, workerCh) }, logging.Labels{ "sync": fmt.Sprintf("att-downloader %v", i), }) }