feat(GODT-2500): Add panic handlers everywhere.

This commit is contained in:
Jakub
2023-03-22 17:18:17 +01:00
parent 9f59e61b14
commit ec92c918cd
42 changed files with 283 additions and 130 deletions

View File

@ -21,6 +21,7 @@ import (
"net/http"
"github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
"github.com/sirupsen/logrus"
@ -32,6 +33,7 @@ func defaultAPIOptions(
version *semver.Version,
cookieJar http.CookieJar,
transport http.RoundTripper,
panicHandler queue.PanicHandler,
) []proton.Option {
return []proton.Option{
proton.WithHostURL(apiURL),
@ -39,5 +41,6 @@ func defaultAPIOptions(
proton.WithCookieJar(cookieJar),
proton.WithTransport(transport),
proton.WithLogger(logrus.StandardLogger()),
proton.WithPanicHandler(panicHandler),
}
}

View File

@ -23,6 +23,7 @@ import (
"net/http"
"github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
)
@ -32,6 +33,7 @@ func newAPIOptions(
version *semver.Version,
cookieJar http.CookieJar,
transport http.RoundTripper,
panicHandler queue.PanicHandler,
) []proton.Option {
return defaultAPIOptions(apiURL, version, cookieJar, transport)
return defaultAPIOptions(apiURL, version, cookieJar, transport, panicHandler)
}

View File

@ -24,6 +24,7 @@ import (
"os"
"github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
)
@ -33,8 +34,9 @@ func newAPIOptions(
version *semver.Version,
cookieJar http.CookieJar,
transport http.RoundTripper,
panicHandler queue.PanicHandler,
) []proton.Option {
opt := defaultAPIOptions(apiURL, version, cookieJar, transport)
opt := defaultAPIOptions(apiURL, version, cookieJar, transport, panicHandler)
if host := os.Getenv("BRIDGE_API_HOST"); host != "" {
opt = append(opt, proton.WithHostURL(host))

View File

@ -93,8 +93,8 @@ type Bridge struct {
// locator is the bridge's locator.
locator Locator
// crashHandler
crashHandler async.PanicHandler
// panicHandler
panicHandler async.PanicHandler
// reporter
reporter reporter.Reporter
@ -143,7 +143,7 @@ func New(
tlsReporter TLSReporter, // the TLS reporter to report TLS errors
roundTripper http.RoundTripper, // the round tripper to use for API requests
proxyCtl ProxyController, // the DoH controller
crashHandler async.PanicHandler,
panicHandler async.PanicHandler,
reporter reporter.Reporter,
uidValidityGenerator imap.UIDValidityGenerator,
@ -151,10 +151,10 @@ func New(
logSMTP bool, // whether to log SMTP activity
) (*Bridge, <-chan events.Event, error) {
// api is the user's API manager.
api := proton.New(newAPIOptions(apiURL, curVersion, cookieJar, roundTripper)...)
api := proton.New(newAPIOptions(apiURL, curVersion, cookieJar, roundTripper, panicHandler)...)
// tasks holds all the bridge's background tasks.
tasks := async.NewGroup(context.Background(), crashHandler)
tasks := async.NewGroup(context.Background(), panicHandler)
// imapEventCh forwards IMAP events from gluon instances to the bridge for processing.
imapEventCh := make(chan imapEvents.Event)
@ -169,7 +169,7 @@ func New(
autostarter,
updater,
curVersion,
crashHandler,
panicHandler,
reporter,
api,
@ -202,7 +202,7 @@ func newBridge(
autostarter Autostarter,
updater Updater,
curVersion *semver.Version,
crashHandler async.PanicHandler,
panicHandler async.PanicHandler,
reporter reporter.Reporter,
api *proton.Manager,
@ -248,12 +248,13 @@ func newBridge(
imapEventCh,
tasks,
uidValidityGenerator,
panicHandler,
)
if err != nil {
return nil, fmt.Errorf("failed to create IMAP server: %w", err)
}
focusService, err := focus.NewService(locator, curVersion)
focusService, err := focus.NewService(locator, curVersion, panicHandler)
if err != nil {
return nil, fmt.Errorf("failed to create focus service: %w", err)
}
@ -279,7 +280,7 @@ func newBridge(
newVersion: curVersion,
newVersionLock: safe.NewRWMutex(),
crashHandler: crashHandler,
panicHandler: panicHandler,
reporter: reporter,
focusService: focusService,
@ -495,7 +496,7 @@ func (bridge *Bridge) addWatcher(ofType ...events.Event) *watcher.Watcher[events
bridge.watchersLock.Lock()
defer bridge.watchersLock.Unlock()
watcher := watcher.New(ofType...)
watcher := watcher.New(bridge.panicHandler, ofType...)
bridge.watchers = append(bridge.watchers, watcher)

View File

@ -31,6 +31,7 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/go-proton-api/server/backend"
@ -699,7 +700,7 @@ func withBridgeNoMocks(
require.NoError(t, err)
// Create the vault.
vault, _, err := vault.New(vaultDir, t.TempDir(), vaultKey)
vault, _, err := vault.New(vaultDir, t.TempDir(), vaultKey, queue.NoopPanicHandler{})
require.NoError(t, err)
// Create a new cookie jar.

View File

@ -299,6 +299,7 @@ func newIMAPServer(
eventCh chan<- imapEvents.Event,
tasks *async.Group,
uidValidityGenerator imap.UIDValidityGenerator,
panicHandler async.PanicHandler,
) (*gluon.Server, error) {
gluonCacheDir = ApplyGluonCachePathSuffix(gluonCacheDir)
gluonConfigDir = ApplyGluonConfigPathSuffix(gluonConfigDir)
@ -343,6 +344,7 @@ func newIMAPServer(
getGluonVersionInfo(version),
gluon.WithReporter(reporter),
gluon.WithUIDValidityGenerator(uidValidityGenerator),
gluon.WithPanicHandler(panicHandler),
)
if err != nil {
return nil, err

View File

@ -157,6 +157,7 @@ func (bridge *Bridge) SetGluonDir(ctx context.Context, newGluonDir string) error
bridge.imapEventCh,
bridge.tasks,
bridge.uidValidityGenerator,
bridge.panicHandler,
)
if err != nil {
return fmt.Errorf("failed to create new IMAP server: %w", err)

View File

@ -28,6 +28,7 @@ import (
"testing"
"time"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
@ -428,7 +429,7 @@ func createMessages(ctx context.Context, t *testing.T, c *proton.Client, addrID,
keyPass, err := salt.SaltForKey(password, user.Keys.Primary().ID)
require.NoError(t, err)
_, addrKRs, err := proton.Unlock(user, addr, keyPass)
_, addrKRs, err := proton.Unlock(user, addr, keyPass, queue.NoopPanicHandler{})
require.NoError(t, err)
_, ok := addrKRs[addrID]

View File

@ -516,7 +516,7 @@ func (bridge *Bridge) addUserWithVault(
client,
bridge.reporter,
apiUser,
bridge.crashHandler,
bridge.panicHandler,
bridge.vault.GetShowAllMail(),
bridge.vault.GetMaxSyncMemory(),
)

View File

@ -28,6 +28,7 @@ import (
"testing"
"time"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
@ -474,7 +475,7 @@ func TestBridge_User_UpdateDraftAndCreateOtherMessage(t *testing.T) {
keyPass, err := salts.SaltForKey(password, user.Keys.Primary().ID)
require.NoError(t, err)
_, addrKRs, err := proton.Unlock(user, addrs, keyPass)
_, addrKRs, err := proton.Unlock(user, addrs, keyPass, queue.NoopPanicHandler{})
require.NoError(t, err)
// Create a draft (generating a "create draft message" event).
@ -556,7 +557,7 @@ func TestBridge_User_SendDraftRemoveDraftFlag(t *testing.T) {
keyPass, err := salts.SaltForKey(password, user.Keys.Primary().ID)
require.NoError(t, err)
_, addrKRs, err := proton.Unlock(user, addrs, keyPass)
_, addrKRs, err := proton.Unlock(user, addrs, keyPass, queue.NoopPanicHandler{})
require.NoError(t, err)
// Create a draft (generating a "create draft message" event).