mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-14 01:42:54 +01:00
Winni Neessen
ee726487f1
Extracted message sending functionality into a new helper function `sendSingleMsg`. This improves the code readability and maintainability by reducing the complexity of the main loop and encapsulating error handling per message.
110 lines
3.1 KiB
Go
110 lines
3.1 KiB
Go
// SPDX-FileCopyrightText: 2022-2023 The go-mail Authors
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
//go:build go1.20
|
|
// +build go1.20
|
|
|
|
package mail
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
// Send sends out the mail message
|
|
func (c *Client) Send(messages ...*Msg) (returnErr error) {
|
|
if err := c.checkConn(); err != nil {
|
|
returnErr = &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)}
|
|
return
|
|
}
|
|
|
|
var errs []error
|
|
defer func() {
|
|
returnErr = errors.Join(errs...)
|
|
}()
|
|
|
|
for _, message := range messages {
|
|
if sendErr := c.sendSingleMsg(message); sendErr != nil {
|
|
message.sendError = sendErr
|
|
errs = append(errs, sendErr)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// sendSingleMsg sends out a single message and returns an error if the transmission/delivery fails.
|
|
// It is invoked by the public Send methods
|
|
func (c *Client) sendSingleMsg(message *Msg) error {
|
|
if message.encoding == NoEncoding {
|
|
if ok, _ := c.smtpClient.Extension("8BITMIME"); !ok {
|
|
return &SendError{Reason: ErrNoUnencoded, isTemp: false}
|
|
}
|
|
}
|
|
from, err := message.GetSender(false)
|
|
if err != nil {
|
|
return &SendError{Reason: ErrGetSender, errlist: []error{err}, isTemp: isTempError(err),
|
|
affectedMsg: message}
|
|
}
|
|
rcpts, err := message.GetRecipients()
|
|
if err != nil {
|
|
return &SendError{Reason: ErrGetRcpts, errlist: []error{err}, isTemp: isTempError(err),
|
|
affectedMsg: message}
|
|
}
|
|
|
|
if c.dsn {
|
|
if c.dsnmrtype != "" {
|
|
c.smtpClient.SetDSNMailReturnOption(string(c.dsnmrtype))
|
|
}
|
|
}
|
|
if err = c.smtpClient.Mail(from); err != nil {
|
|
retError := &SendError{Reason: ErrSMTPMailFrom, errlist: []error{err}, isTemp: isTempError(err)}
|
|
if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil {
|
|
retError.errlist = append(retError.errlist, resetSendErr)
|
|
}
|
|
return retError
|
|
}
|
|
failed := false
|
|
rcptSendErr := &SendError{}
|
|
rcptSendErr.errlist = make([]error, 0)
|
|
rcptSendErr.rcpt = make([]string, 0)
|
|
rcptNotifyOpt := strings.Join(c.dsnrntype, ",")
|
|
c.smtpClient.SetDSNRcptNotifyOption(rcptNotifyOpt)
|
|
for _, rcpt := range rcpts {
|
|
if err = c.smtpClient.Rcpt(rcpt); err != nil {
|
|
rcptSendErr.Reason = ErrSMTPRcptTo
|
|
rcptSendErr.errlist = append(rcptSendErr.errlist, err)
|
|
rcptSendErr.rcpt = append(rcptSendErr.rcpt, rcpt)
|
|
rcptSendErr.isTemp = isTempError(err)
|
|
failed = true
|
|
}
|
|
}
|
|
if failed {
|
|
if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil {
|
|
rcptSendErr.errlist = append(rcptSendErr.errlist, resetSendErr)
|
|
}
|
|
return rcptSendErr
|
|
}
|
|
writer, err := c.smtpClient.Data()
|
|
if err != nil {
|
|
return &SendError{Reason: ErrSMTPData, errlist: []error{err}, isTemp: isTempError(err)}
|
|
}
|
|
_, err = message.WriteTo(writer)
|
|
if err != nil {
|
|
return &SendError{Reason: ErrWriteContent, errlist: []error{err}, isTemp: isTempError(err)}
|
|
}
|
|
message.isDelivered = true
|
|
|
|
if err = writer.Close(); err != nil {
|
|
return &SendError{Reason: ErrSMTPDataClose, errlist: []error{err}, isTemp: isTempError(err)}
|
|
}
|
|
|
|
if err = c.Reset(); err != nil {
|
|
return &SendError{Reason: ErrSMTPReset, errlist: []error{err}, isTemp: isTempError(err)}
|
|
}
|
|
if err = c.checkConn(); err != nil {
|
|
return &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)}
|
|
}
|
|
return nil
|
|
}
|