mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-22 13:50:49 +01:00
Winni Neessen
48b4dc6b6c
`Client.Send()` provides the possibility to send multiple `*Msg` in one go. If one of the `*Msg` caused an error with the sending mail server, we were returning completely, while not processing any `*Msg` that came after the failing message. This PR fixes this behaviour by processing each message first and then return a accumulated error in case any of the `*Msg` processing failed Additionally, this PR separates the `Client.Send()` method into two different versions. One that makes use of the new `errors.Join()` functionality that is introduced with Go 1.20 and one that handles it the old way for any supported version lower than Go 1.20
85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
// SPDX-FileCopyrightText: 2022 Winni Neessen <winni@neessen.dev>
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
//go:build go1.20
|
|
// +build go1.20
|
|
|
|
package mail
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// Send sends out the mail message
|
|
func (c *Client) Send(ml ...*Msg) (rerr error) {
|
|
if err := c.checkConn(); err != nil {
|
|
rerr = fmt.Errorf("failed to send mail: %w", err)
|
|
return
|
|
}
|
|
for _, m := range ml {
|
|
if m.encoding == NoEncoding {
|
|
if ok, _ := c.sc.Extension("8BITMIME"); !ok {
|
|
rerr = errors.Join(rerr, ErrServerNoUnencoded)
|
|
continue
|
|
}
|
|
}
|
|
f, err := m.GetSender(false)
|
|
if err != nil {
|
|
rerr = errors.Join(rerr, err)
|
|
continue
|
|
}
|
|
rl, err := m.GetRecipients()
|
|
if err != nil {
|
|
rerr = errors.Join(rerr, err)
|
|
continue
|
|
}
|
|
|
|
if err := c.mail(f); err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("sending MAIL FROM command failed: %w", err))
|
|
if reserr := c.sc.Reset(); reserr != nil {
|
|
rerr = errors.Join(rerr, reserr)
|
|
}
|
|
continue
|
|
}
|
|
failed := false
|
|
for _, r := range rl {
|
|
if err := c.rcpt(r); err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("sending RCPT TO command failed: %w", err))
|
|
failed = true
|
|
}
|
|
}
|
|
if failed {
|
|
if reserr := c.sc.Reset(); reserr != nil {
|
|
rerr = errors.Join(rerr, reserr)
|
|
}
|
|
continue
|
|
}
|
|
w, err := c.sc.Data()
|
|
if err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("sending DATA command failed: %w", err))
|
|
continue
|
|
}
|
|
_, err = m.WriteTo(w)
|
|
if err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("sending mail content failed: %w", err))
|
|
continue
|
|
}
|
|
|
|
if err := w.Close(); err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("failed to close DATA writer: %w", err))
|
|
continue
|
|
}
|
|
|
|
if err := c.Reset(); err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("sending RSET command failed: %w", err))
|
|
continue
|
|
}
|
|
if err := c.checkConn(); err != nil {
|
|
rerr = errors.Join(rerr, fmt.Errorf("failed to check server connection: %w", err))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|