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