forked from Silverfish/proton-bridge
GODT-2187: Handle unbuildable messages in event loop
This commit is contained in:
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ProtonMail/gluon/imap"
|
"github.com/ProtonMail/gluon/imap"
|
||||||
"github.com/ProtonMail/gluon/queue"
|
"github.com/ProtonMail/gluon/queue"
|
||||||
|
"github.com/ProtonMail/gluon/reporter"
|
||||||
"github.com/ProtonMail/go-proton-api"
|
"github.com/ProtonMail/go-proton-api"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||||
@ -438,13 +439,30 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event proton.Mes
|
|||||||
}).Info("Handling message created event")
|
}).Info("Handling message created event")
|
||||||
|
|
||||||
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
||||||
buildRes := buildRFC822(user.apiLabels, full, addrKR)
|
res := buildRFC822(user.apiLabels, full, addrKR)
|
||||||
|
|
||||||
if buildRes.err != nil {
|
if res.err != nil {
|
||||||
return fmt.Errorf("failed to build RFC822 message: %w", err)
|
user.log.WithError(err).Error("Failed to build RFC822 message")
|
||||||
|
|
||||||
|
if err := user.vault.AddFailedMessageID(event.ID); err != nil {
|
||||||
|
user.log.WithError(err).Error("Failed to add failed message ID to vault")
|
||||||
}
|
}
|
||||||
|
|
||||||
user.updateCh[full.AddressID].Enqueue(imap.NewMessagesCreated(buildRes.update))
|
if err := user.reporter.ReportMessageWithContext("Failed to build message (event create)", reporter.Context{
|
||||||
|
"messageID": res.messageID,
|
||||||
|
"error": res.err,
|
||||||
|
}); err != nil {
|
||||||
|
user.log.WithError(err).Error("Failed to report message build error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := user.vault.RemFailedMessageID(event.ID); err != nil {
|
||||||
|
user.log.WithError(err).Error("Failed to remove failed message ID from vault")
|
||||||
|
}
|
||||||
|
|
||||||
|
user.updateCh[full.AddressID].Enqueue(imap.NewMessagesCreated(res.update))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -494,17 +512,34 @@ func (user *User) handleUpdateDraftEvent(ctx context.Context, event proton.Messa
|
|||||||
}
|
}
|
||||||
|
|
||||||
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
|
||||||
buildRes := buildRFC822(user.apiLabels, full, addrKR)
|
res := buildRFC822(user.apiLabels, full, addrKR)
|
||||||
|
|
||||||
if buildRes.err != nil {
|
if res.err != nil {
|
||||||
return fmt.Errorf("failed to build RFC822 draft: %w", err)
|
logrus.WithError(err).Error("Failed to build RFC822 message")
|
||||||
|
|
||||||
|
if err := user.vault.AddFailedMessageID(event.ID); err != nil {
|
||||||
|
user.log.WithError(err).Error("Failed to add failed message ID to vault")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := user.reporter.ReportMessageWithContext("Failed to build message (event update)", reporter.Context{
|
||||||
|
"messageID": res.messageID,
|
||||||
|
"error": res.err,
|
||||||
|
}); err != nil {
|
||||||
|
logrus.WithError(err).Error("Failed to report message build error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := user.vault.RemFailedMessageID(event.ID); err != nil {
|
||||||
|
user.log.WithError(err).Error("Failed to remove failed message ID from vault")
|
||||||
}
|
}
|
||||||
|
|
||||||
user.updateCh[full.AddressID].Enqueue(imap.NewMessageUpdated(
|
user.updateCh[full.AddressID].Enqueue(imap.NewMessageUpdated(
|
||||||
buildRes.update.Message,
|
res.update.Message,
|
||||||
buildRes.update.Literal,
|
res.update.Literal,
|
||||||
buildRes.update.MailboxIDs,
|
res.update.MailboxIDs,
|
||||||
buildRes.update.ParsedMessage,
|
res.update.ParsedMessage,
|
||||||
))
|
))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -304,11 +304,11 @@ func syncMessages(
|
|||||||
logrus.WithError(err).Error("Failed to add failed message ID")
|
logrus.WithError(err).Error("Failed to add failed message ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sentry.ReportMessageWithContext("Failed to sync message", reporter.Context{
|
if err := sentry.ReportMessageWithContext("Failed to build message (sync)", reporter.Context{
|
||||||
"messageID": res.messageID,
|
"messageID": res.messageID,
|
||||||
"error": res.err,
|
"error": res.err,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
logrus.WithError(err).Error("Failed to report message sync error")
|
logrus.WithError(err).Error("Failed to report message build error")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could sync a placeholder message here, but for now we skip it entirely.
|
// We could sync a placeholder message here, but for now we skip it entirely.
|
||||||
|
|||||||
@ -120,7 +120,7 @@ func newFailedMessageLiteral(
|
|||||||
if tmpl, err := template.New("header").Parse(failedMessageHeaderTemplate); err != nil {
|
if tmpl, err := template.New("header").Parse(failedMessageHeaderTemplate); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else if b, err := tmplExec(tmpl, map[string]any{
|
} else if b, err := tmplExec(tmpl, map[string]any{
|
||||||
"Date": date.Format(time.RFC822),
|
"Date": date.In(time.UTC).Format(time.RFC822),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
} else if _, err := buf.Write(b); err != nil {
|
} else if _, err := buf.Write(b); err != nil {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ func TestNewFailedMessageLiteral(t *testing.T) {
|
|||||||
header, err := rfc822.Parse(literal).ParseHeader()
|
header, err := rfc822.Parse(literal).ParseHeader()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "Message failed to build", header.Get("Subject"))
|
require.Equal(t, "Message failed to build", header.Get("Subject"))
|
||||||
require.Equal(t, "29 Nov 73 22:33 CET", header.Get("Date"))
|
require.Equal(t, "29 Nov 73 21:33 UTC", header.Get("Date"))
|
||||||
require.Equal(t, "text/plain", header.Get("Content-Type"))
|
require.Equal(t, "text/plain", header.Get("Content-Type"))
|
||||||
require.Equal(t, "base64", header.Get("Content-Transfer-Encoding"))
|
require.Equal(t, "base64", header.Get("Content-Transfer-Encoding"))
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ func TestNewFailedMessageLiteral(t *testing.T) {
|
|||||||
|
|
||||||
parsed, err := imap.NewParsedMessage(literal)
|
parsed, err := imap.NewParsedMessage(literal)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, `("29 Nov 73 22:33 CET" "Message failed to build" NIL NIL NIL NIL NIL NIL NIL NIL)`, parsed.Envelope)
|
require.Equal(t, `("29 Nov 73 21:33 UTC" "Message failed to build" NIL NIL NIL NIL NIL NIL NIL NIL)`, parsed.Envelope)
|
||||||
require.Equal(t, `("text" "plain" () NIL NIL "base64" 114 2)`, parsed.Body)
|
require.Equal(t, `("text" "plain" () NIL NIL "base64" 114 2)`, parsed.Body)
|
||||||
require.Equal(t, `("text" "plain" () NIL NIL "base64" 114 2 NIL NIL NIL NIL)`, parsed.Structure)
|
require.Equal(t, `("text" "plain" () NIL NIL "base64" 114 2 NIL NIL NIL NIL)`, parsed.Structure)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user