mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-15 22:56:48 +00:00
feat(BRIDGE-376): catch gluon errors related to label uniqueness constrainst...
This commit is contained in:
@ -108,8 +108,6 @@ func (t *Handler) Execute(
|
||||
t.log.WithError(err).Error("Sync aborted")
|
||||
break
|
||||
} else if err = t.run(ctx, syncReporter, labels, updateApplier, messageBuilder); err != nil {
|
||||
t.log.WithError(err).Error("Failed to sync, will retry later")
|
||||
|
||||
if sentryErr := t.sentryReporter.ReportMessageWithContext("Failed to sync, will retry later", reporter.Context{
|
||||
"err": err.Error(),
|
||||
"user_id": t.userID,
|
||||
@ -117,6 +115,7 @@ func (t *Handler) Execute(
|
||||
t.log.WithError(sentryErr).Error("Failed to report sentry message")
|
||||
}
|
||||
|
||||
t.log.WithError(err).Error("Failed to sync, will retry later")
|
||||
sleepCtx(ctx, coolDown)
|
||||
} else {
|
||||
break
|
||||
|
||||
@ -29,6 +29,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/gluon/async"
|
||||
"github.com/ProtonMail/gluon/db"
|
||||
"github.com/ProtonMail/gluon/reporter"
|
||||
"github.com/ProtonMail/gluon/watcher"
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal"
|
||||
@ -70,6 +72,8 @@ type Service struct {
|
||||
eventPollWaitersLock sync.Mutex
|
||||
eventSubscription events.Subscription
|
||||
eventWatcher *watcher.Watcher[events.Event]
|
||||
|
||||
sentryReporter reporter.Reporter
|
||||
}
|
||||
|
||||
func NewService(
|
||||
@ -82,6 +86,7 @@ func NewService(
|
||||
eventTimeout time.Duration,
|
||||
panicHandler async.PanicHandler,
|
||||
eventSubscription events.Subscription,
|
||||
sentryReporter reporter.Reporter,
|
||||
) *Service {
|
||||
return &Service{
|
||||
cpc: cpc.NewCPC(),
|
||||
@ -99,6 +104,7 @@ func NewService(
|
||||
panicHandler: panicHandler,
|
||||
eventSubscription: eventSubscription,
|
||||
eventWatcher: eventSubscription.Add(events.ConnStatusDown{}, events.ConnStatusUp{}),
|
||||
sentryReporter: sentryReporter,
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,6 +420,14 @@ func (s *Service) handleEventError(ctx context.Context, lastEventID string, even
|
||||
return subscriberName, fmt.Errorf("failed to handle event due to server error: %w", err)
|
||||
}
|
||||
|
||||
if db.IsUniqueLabelConstraintError(err) {
|
||||
if err := s.sentryReporter.ReportMessageWithContext("Unique label constraint error occurred on event", reporter.Context{
|
||||
"err": err,
|
||||
}); err != nil {
|
||||
s.log.WithError(err).Error("Failed to report label constraint error to sentry")
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, the error is a client-side issue; notify bridge to handle it.
|
||||
s.log.WithField("event", event).Warn("Failed to handle API event")
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import (
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events/mocks"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/sentry"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -49,6 +50,7 @@ func TestServiceHandleEventError_SubscriberEventUnwrapping(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
lastEventID := "PrevEvent"
|
||||
@ -87,6 +89,7 @@ func TestServiceHandleEventError_BadEventPutsServiceOnPause(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
service.Resume()
|
||||
lastEventID := "PrevEvent"
|
||||
@ -121,6 +124,7 @@ func TestServiceHandleEventError_BadEventFromPublishTimeout(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
lastEventID := "PrevEvent"
|
||||
event := proton.Event{EventID: "MyEvent"}
|
||||
@ -152,6 +156,7 @@ func TestServiceHandleEventError_NoBadEventCheck(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
lastEventID := "PrevEvent"
|
||||
event := proton.Event{EventID: "MyEvent"}
|
||||
@ -178,6 +183,7 @@ func TestServiceHandleEventError_JsonUnmarshalEventProducesUncategorizedErrorEve
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
lastEventID := "PrevEvent"
|
||||
event := proton.Event{EventID: "MyEvent"}
|
||||
|
||||
@ -28,6 +28,7 @@ import (
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events/mocks"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/sentry"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -69,6 +70,7 @@ func TestServiceHandleEvent_CheckEventCategoriesHandledInOrder(t *testing.T) {
|
||||
10*time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscription := NewCallbackSubscriber("test", EventHandler{
|
||||
@ -130,6 +132,7 @@ func TestServiceHandleEvent_CheckEventFailureCausesError(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscription := NewCallbackSubscriber("test", EventHandler{
|
||||
@ -168,6 +171,7 @@ func TestServiceHandleEvent_CheckEventFailureCausesErrorParallel(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscription := NewCallbackSubscriber("test", EventHandler{
|
||||
|
||||
@ -27,6 +27,7 @@ import (
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||
mocks2 "github.com/ProtonMail/proton-bridge/v3/internal/events/mocks"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/sentry"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/services/orderedtasks"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/services/userevents/mocks"
|
||||
"github.com/golang/mock/gomock"
|
||||
@ -76,6 +77,7 @@ func TestService_EventIDLoadStore(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
_, err := service.Start(context.Background(), group)
|
||||
@ -132,6 +134,7 @@ func TestService_RetryEventOnNonCatastrophicFailure(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
service.Subscribe(NewCallbackSubscriber("foo", EventHandler{MessageHandler: subscriber}))
|
||||
|
||||
@ -182,6 +185,7 @@ func TestService_OnBadEventServiceIsPaused(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
// Event publisher expectations.
|
||||
@ -249,6 +253,7 @@ func TestService_UnsubscribeDuringEventHandlingDoesNotCauseDeadlock(t *testing.T
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscription := NewCallbackSubscriber("foo", EventHandler{MessageHandler: subscriber})
|
||||
@ -309,6 +314,7 @@ func TestService_UnsubscribeBeforeHandlingEventIsNotConsideredError(t *testing.T
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscription := NewEventSubscriber("Foo")
|
||||
@ -369,6 +375,7 @@ func TestService_WaitOnEventPublishAfterPause(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
subscriber.EXPECT().HandleMessageEvents(gomock.Any(), gomock.Eq(messageEvents)).Times(1).DoAndReturn(func(_ context.Context, _ []proton.MessageEvent) error {
|
||||
@ -442,6 +449,7 @@ func TestService_EventRewind(t *testing.T) {
|
||||
time.Second,
|
||||
async.NoopPanicHandler{},
|
||||
events.NewNullSubscription(),
|
||||
sentry.NullSentryReporter{},
|
||||
)
|
||||
|
||||
_, err := service.Start(context.Background(), group)
|
||||
|
||||
Reference in New Issue
Block a user