Add additional error handling to email message sending. (#1639)
* Adding additional error handling to email message sending. * Adding additional error handling to email message sending. * Fixing issue with err being lost in the defer. * Moving defers to be queued up earlier to ensure they get called. * Fixed closing encoder to use defer pattern that matches the others.
This commit is contained in:
parent
1d1040accd
commit
7ce9a60c85
@ -12,6 +12,8 @@ import (
|
||||
"mime/quotedprintable"
|
||||
"net/textproto"
|
||||
"time"
|
||||
|
||||
"github.com/zeebo/errs"
|
||||
)
|
||||
|
||||
// Message is RFC compliant email message
|
||||
@ -35,8 +37,11 @@ type Part struct {
|
||||
Content string
|
||||
}
|
||||
|
||||
// Error is the default message errs class
|
||||
var Error = errs.Class("Email message error")
|
||||
|
||||
// Bytes builds message and returns result as bytes
|
||||
func (msg *Message) Bytes() []byte {
|
||||
func (msg *Message) Bytes() (data []byte, err error) {
|
||||
// always returns nil error on read and write, so most of the errors can be ignored
|
||||
var body bytes.Buffer
|
||||
|
||||
@ -62,6 +67,7 @@ func (msg *Message) Bytes() []byte {
|
||||
// multipart upload
|
||||
case len(msg.Parts) > 0:
|
||||
wr := multipart.NewWriter(&body)
|
||||
defer func() { err = errs.Combine(err, wr.Close()) }()
|
||||
|
||||
fmt.Fprintf(&body, "Content-Type: multipart/alternative;")
|
||||
fmt.Fprintf(&body, "\tboundary=\"%v\"\r\n", wr.Boundary())
|
||||
@ -70,14 +76,21 @@ func (msg *Message) Bytes() []byte {
|
||||
var sub io.Writer
|
||||
|
||||
if len(msg.PlainText) > 0 {
|
||||
sub, _ = wr.CreatePart(textproto.MIMEHeader{
|
||||
sub, err := wr.CreatePart(textproto.MIMEHeader{
|
||||
"Content-Type": []string{"text/plain; charset=UTF-8; format=flowed"},
|
||||
"Content-Transfer-Encoding": []string{"quoted-printable"},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
enc := quotedprintable.NewWriter(sub)
|
||||
_, _ = enc.Write([]byte(msg.PlainText))
|
||||
_ = enc.Close()
|
||||
defer func() { err = errs.Combine(err, enc.Close()) }()
|
||||
|
||||
_, err = enc.Write([]byte(msg.PlainText))
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, part := range msg.Parts {
|
||||
@ -93,18 +106,20 @@ func (msg *Message) Bytes() []byte {
|
||||
fmt.Fprint(sub, part.Content)
|
||||
}
|
||||
|
||||
_ = wr.Close()
|
||||
// fallback if there are no parts, write PlainText with appropriate Content-Type
|
||||
default:
|
||||
fmt.Fprintf(&body, "Content-Type: text/plain; charset=UTF-8; format=flowed\r\n")
|
||||
fmt.Fprintf(&body, "Content-Transfer-Encoding: quoted-printable\r\n\r\n")
|
||||
|
||||
enc := quotedprintable.NewWriter(&body)
|
||||
_, _ = enc.Write([]byte(msg.PlainText))
|
||||
_ = enc.Close()
|
||||
defer func() { err = errs.Combine(err, enc.Close()) }()
|
||||
|
||||
if _, err := enc.Write([]byte(msg.PlainText)); err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return tocrlf(body.Bytes())
|
||||
return tocrlf(body.Bytes()), nil
|
||||
}
|
||||
|
||||
func tocrlf(data []byte) []byte {
|
||||
|
@ -76,7 +76,12 @@ func (sender *SMTPSender) SendEmail(msg *Message) error {
|
||||
err = errs.Combine(err, data.Close())
|
||||
}()
|
||||
|
||||
_, err = data.Write(msg.Bytes())
|
||||
mess, err := msg.Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = data.Write(mess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user