Refactor message sending logic for better modularity

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.
This commit is contained in:
Winni Neessen 2024-09-18 11:06:48 +02:00
parent 1dd73778d4
commit ee726487f1
Signed by: wneessen
GPG key ID: 5F3AF39B820C119D

View file

@ -24,28 +24,33 @@ func (c *Client) Send(messages ...*Msg) (returnErr error) {
returnErr = errors.Join(errs...) returnErr = errors.Join(errs...)
}() }()
for msgid, message := range messages { for _, message := range messages {
message.sendError = nil 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 message.encoding == NoEncoding {
if ok, _ := c.smtpClient.Extension("8BITMIME"); !ok { if ok, _ := c.smtpClient.Extension("8BITMIME"); !ok {
message.sendError = &SendError{Reason: ErrNoUnencoded, isTemp: false} return &SendError{Reason: ErrNoUnencoded, isTemp: false}
errs = append(errs, message.sendError)
continue
} }
} }
from, err := message.GetSender(false) from, err := message.GetSender(false)
if err != nil { if err != nil {
message.sendError = &SendError{Reason: ErrGetSender, errlist: []error{err}, isTemp: isTempError(err), return &SendError{Reason: ErrGetSender, errlist: []error{err}, isTemp: isTempError(err),
affectedMsg: messages[msgid]} affectedMsg: message}
errs = append(errs, message.sendError)
continue
} }
rcpts, err := message.GetRecipients() rcpts, err := message.GetRecipients()
if err != nil { if err != nil {
message.sendError = &SendError{Reason: ErrGetRcpts, errlist: []error{err}, isTemp: isTempError(err), return &SendError{Reason: ErrGetRcpts, errlist: []error{err}, isTemp: isTempError(err),
affectedMsg: messages[msgid]} affectedMsg: message}
errs = append(errs, message.sendError)
continue
} }
if c.dsn { if c.dsn {
@ -54,12 +59,11 @@ func (c *Client) Send(messages ...*Msg) (returnErr error) {
} }
} }
if err = c.smtpClient.Mail(from); err != nil { if err = c.smtpClient.Mail(from); err != nil {
message.sendError = &SendError{Reason: ErrSMTPMailFrom, errlist: []error{err}, isTemp: isTempError(err)} retError := &SendError{Reason: ErrSMTPMailFrom, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil { if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil {
errs = append(errs, resetSendErr) retError.errlist = append(retError.errlist, resetSendErr)
} }
continue return retError
} }
failed := false failed := false
rcptSendErr := &SendError{} rcptSendErr := &SendError{}
@ -78,42 +82,29 @@ func (c *Client) Send(messages ...*Msg) (returnErr error) {
} }
if failed { if failed {
if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil { if resetSendErr := c.smtpClient.Reset(); resetSendErr != nil {
errs = append(errs, resetSendErr) rcptSendErr.errlist = append(rcptSendErr.errlist, resetSendErr)
} }
message.sendError = rcptSendErr return rcptSendErr
errs = append(errs, message.sendError)
continue
} }
writer, err := c.smtpClient.Data() writer, err := c.smtpClient.Data()
if err != nil { if err != nil {
message.sendError = &SendError{Reason: ErrSMTPData, errlist: []error{err}, isTemp: isTempError(err)} return &SendError{Reason: ErrSMTPData, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
continue
} }
_, err = message.WriteTo(writer) _, err = message.WriteTo(writer)
if err != nil { if err != nil {
message.sendError = &SendError{Reason: ErrWriteContent, errlist: []error{err}, isTemp: isTempError(err)} return &SendError{Reason: ErrWriteContent, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
continue
} }
message.isDelivered = true message.isDelivered = true
if err = writer.Close(); err != nil { if err = writer.Close(); err != nil {
message.sendError = &SendError{Reason: ErrSMTPDataClose, errlist: []error{err}, isTemp: isTempError(err)} return &SendError{Reason: ErrSMTPDataClose, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
continue
} }
if err = c.Reset(); err != nil { if err = c.Reset(); err != nil {
message.sendError = &SendError{Reason: ErrSMTPReset, errlist: []error{err}, isTemp: isTempError(err)} return &SendError{Reason: ErrSMTPReset, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
continue
} }
if err = c.checkConn(); err != nil { if err = c.checkConn(); err != nil {
message.sendError = &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)} return &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)}
errs = append(errs, message.sendError)
} }
} return nil
return
} }