From 713be1e72656395e7c8ce83fc6c2f6646c3d5231 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 12 Feb 2026 08:44:57 +0100 Subject: [PATCH 1/4] refactor(service): update alias.go --- api/internal/service/alias.go | 8 ++++---- api/internal/service/processor.go | 7 +++---- api/internal/service/recipient.go | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/api/internal/service/alias.go b/api/internal/service/alias.go index f699bf37..5fe5a530 100644 --- a/api/internal/service/alias.go +++ b/api/internal/service/alias.go @@ -13,7 +13,8 @@ import ( var ( ErrGetAlias = errors.New("Unable to retrieve alias by ID.") ErrGetAliases = errors.New("Unable to retrieve aliases.") - ErrGetAliasByName = errors.New("Unable to retrieve alias by name.") + ErrGetAliasByName = errors.New("alias not found:") + ErrDisabledAlias = errors.New("alias disabled:") ErrPostAlias = errors.New("Unable to create alias. Please try again.") ErrPostAliasLimit = errors.New("You’ve reached the maximum number of allowed aliases.") ErrUpdateAlias = errors.New("Unable to update alias. Please try again.") @@ -81,8 +82,7 @@ func (s *Service) GetAllAliases(ctx context.Context, userID string) ([]model.Ali func (s *Service) GetAliasByName(name string) (model.Alias, error) { alias, err := s.Store.GetAliasByName(name) if err != nil { - log.Printf("error fetching alias %s: %s", name, err.Error()) - return model.Alias{}, ErrGetAliasByName + return model.Alias{Name: name}, ErrGetAliasByName } return alias, nil @@ -193,7 +193,7 @@ func (s *Service) FindAlias(email string) (model.Alias, error) { name, _ := model.ParseReplyTo(email) alias, err := s.GetAliasByName(name) if err != nil { - return model.Alias{}, err + return model.Alias{Name: name}, err } return alias, nil diff --git a/api/internal/service/processor.go b/api/internal/service/processor.go index 7d7c9e9a..e8554d12 100644 --- a/api/internal/service/processor.go +++ b/api/internal/service/processor.go @@ -13,7 +13,6 @@ import ( var ( ErrInactiveSubscription = errors.New("Subscription is inactive.") - ErrDisabledAlias = errors.New("This alias is disabled.") ErrNoRecipients = errors.New("No recipients found.") ErrNoVerifiedRecipients = errors.New("Sender is not a verified address.") ErrInactiveRecipient = errors.New("The recipient is inactive.") @@ -30,13 +29,13 @@ func (s *Service) ProcessMessage(data []byte) error { if msg.Type == model.FailBounce { alias, err := s.FindAlias(msg.From) if err != nil { - log.Println("error processing bounce", err) + log.Println("error processing bounce:", err, alias.Name) return err } err = s.ProcessBounceLog(alias.UserID, alias.ID, data, msg) if err != nil { - log.Println("error processing bounce", err) + log.Println("error processing bounce:", err, alias.Name) return err } @@ -58,7 +57,7 @@ func (s *Service) ProcessMessage(data []byte) error { for _, to := range msg.To { recipients, alias, relayType, err := s.FindRecipients(msg.From, to, msg.Type) if err != nil { - log.Println("error processing message", err) + log.Println("error processing message:", err, alias.Name) // Handle ErrNoVerifiedRecipients if errors.Is(err, ErrNoVerifiedRecipients) { diff --git a/api/internal/service/recipient.go b/api/internal/service/recipient.go index 347ba4ec..3404cd47 100644 --- a/api/internal/service/recipient.go +++ b/api/internal/service/recipient.go @@ -298,7 +298,7 @@ func (s *Service) FindRecipients(from string, to string, msgType model.MessageTy name, replyTo := model.ParseReplyTo(to) alias, err := s.GetAliasByName(name) if err != nil { - return []model.Recipient{}, model.Alias{}, 0, err + return []model.Recipient{}, model.Alias{Name: name}, 0, err } // Handle disabled alias From ab7690102deafec87778670ed134fb266c3146df Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 12 Feb 2026 08:55:33 +0100 Subject: [PATCH 2/4] refactor(service): update processor.go --- api/internal/service/processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/internal/service/processor.go b/api/internal/service/processor.go index e8554d12..54139dc8 100644 --- a/api/internal/service/processor.go +++ b/api/internal/service/processor.go @@ -21,7 +21,7 @@ var ( func (s *Service) ProcessMessage(data []byte) error { msg, err := model.ParseMsg(data) if err != nil { - log.Println("error parsing message", err) + log.Println("error parsing message:", err) return err } From 6089b9f835725a62e4c3fa4ecf566f37571dc839 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 12 Feb 2026 10:14:29 +0100 Subject: [PATCH 3/4] refactor(service): update processor.go --- api/internal/service/processor.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/internal/service/processor.go b/api/internal/service/processor.go index 54139dc8..09174976 100644 --- a/api/internal/service/processor.go +++ b/api/internal/service/processor.go @@ -30,13 +30,11 @@ func (s *Service) ProcessMessage(data []byte) error { alias, err := s.FindAlias(msg.From) if err != nil { log.Println("error processing bounce:", err, alias.Name) - return err } err = s.ProcessBounceLog(alias.UserID, alias.ID, data, msg) if err != nil { log.Println("error processing bounce:", err, alias.Name) - return err } return nil From 98fdd11b57da0db4718a5fe8db77131880513a1a Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 12 Feb 2026 10:52:48 +0100 Subject: [PATCH 4/4] refactor(model): update msg.go --- api/internal/model/msg.go | 7 ++++++- api/internal/service/processor.go | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/api/internal/model/msg.go b/api/internal/model/msg.go index 7d8a1dc7..f4e60ad3 100644 --- a/api/internal/model/msg.go +++ b/api/internal/model/msg.go @@ -13,6 +13,10 @@ import ( "ivpn.net/email/api/internal/utils" ) +var ( + ErrExtractOriginalFrom = fmt.Errorf("error extracting original From from bounce") +) + type Msg struct { From string FromName string @@ -69,7 +73,8 @@ func ParseMsg(data []byte) (Msg, error) { msgType = FailBounce fromAddress, err = ExtractOriginalFrom(processedData) if err != nil { - return Msg{}, fmt.Errorf("extract original from bounce: %w", err) + log.Println("error extracting original From from bounce:", err) + return Msg{}, ErrExtractOriginalFrom } } diff --git a/api/internal/service/processor.go b/api/internal/service/processor.go index 09174976..ab473610 100644 --- a/api/internal/service/processor.go +++ b/api/internal/service/processor.go @@ -21,6 +21,11 @@ var ( func (s *Service) ProcessMessage(data []byte) error { msg, err := model.ParseMsg(data) if err != nil { + if errors.Is(err, model.ErrExtractOriginalFrom) { + // Fail silently so bounce messages are not kept in postfix queue + return nil + } + log.Println("error parsing message:", err) return err } @@ -30,6 +35,8 @@ func (s *Service) ProcessMessage(data []byte) error { alias, err := s.FindAlias(msg.From) if err != nil { log.Println("error processing bounce:", err, alias.Name) + // Fail silently so bounce messages are not kept in postfix queue + return nil } err = s.ProcessBounceLog(alias.UserID, alias.ID, data, msg) @@ -37,6 +44,7 @@ func (s *Service) ProcessMessage(data []byte) error { log.Println("error processing bounce:", err, alias.Name) } + // Fail silently so bounce messages are not kept in postfix queue return nil }