go-gomail / gomail

The best way to send emails in Go.
MIT License
4.3k stars 570 forks source link

Unable to Retrieve textproto.Error When Using gomail.Send() #102

Open jordan-wright opened 6 years ago

jordan-wright commented 6 years ago

It's useful to retrieve the *textproto.Error when sending emails so my client will know how best to handle the error.

I see in #37 that this used to be possible, but it looks like future changes wrapped the changes in a generic error string that makes it seemingly impossible to retrieve the original *textproto.Error: https://github.com/go-gomail/gomail/blob/master/send.go#L39.

I see the value in indicating the index that this error occurred on, but maybe this could be wrapped in a struct that implements the error interface or something? Without the ability to access the underlying error, it's difficult to write a compliant smtp client.

ivy commented 6 years ago

@jordan-wright Could I interest you in opening a pull request fixing this on go-mail/mail#12?

jordan-wright commented 6 years ago

Hey @ivy! I wound up doing what you did and just making a fork that lives at https://github.com/gophish/gomail. I can probably make a pull req when I get some time, I'll just need to figure out how to cherry-pick that commit for review.

jordan-wright commented 6 years ago

If it helps, I think this was the commit https://github.com/gophish/gomail/commit/28cec6d6a23118ee6dcedcf31edca5727aa3d657

ivy commented 6 years ago

Thanks @jordan-wright. I see you also had a use for Reset() (#79) and embedding/attaching an io.Reader (#78). I'm looking to get those changes integrated soon. 😉

I'm hoping to keep some of the error context around with a custom error similar to:

// A SendError represents the failed transmission of a Message and details the
// original error and index of the Message if it was part of a batch.
type SendError struct {
  // Index specifies the index of the Message, if it was part of a batch.
  Index uint

  // Cause specifies the error detailing the original cause of the failure.
  Cause error
}

func (err *SendError) Error() string {
    return fmt.Sprintf("gomail: could not send email %d: %v",
        err.Index, err.Cause)
}