-
-
Notifications
You must be signed in to change notification settings - Fork 79
Error Registry
As of version 0.7.0, go-mail provides a custom error handling registry for the SMTP client, which allows users to handle protocol specific errors, i. e. for SMTP servers with non-RFC-complient responses.
This page provides a currated list of tested error registry handlers for known errors.
In some cases, qq.com is known for sending back arbitrary binary data after issuing a QUIT
command. Instead
of the expected 221 Bye.
response, the server will first send a sequence of binary bytes before finally issuing
back the 221 Bye.
response. Since the SMTP client makes use of net/textproto
the binary data will cause
a short response
error and respectivly cause the QUIT
command to throw and error. The provided error handler
will inject itself into the QUIT
command and check if the error holds the specific byte sequence. If the
byte sequence matches, it will consume those bytes and return back to the SMTP client to handle the standard
response.
// QQMailQuitErrorHandler handles the common error for smtp.qq.com that returns arbitrary binary data after
// the QUIT command, before returning the expected "221 Bye" response
type QQMailQuitErrorHandler struct{}
func (q *QQMailQuitErrorHandler) HandleError(_, _ string, conn *textproto.Conn, err error) error {
var tpErr textproto.ProtocolError
if errors.As(err, &tpErr) {
if len(tpErr.Error()) < 16 {
return err
}
if !bytes.Equal([]byte(tpErr.Error()[16:]), []byte("\x00\x00\x00\x1a\x00\x00\x00")) {
return err
}
_, _ = io.ReadFull(conn.R, make([]byte, 8))
return nil
}
return err
}
client, err := mail.NewClient("smtp.qq.com", mail.WithPort(465), mail.WithSSL())
if err != nil {
log.Fatalf("failed to create client: %s\n", err)
}
qqMailQuitErrorHandler := &QQMailQuitErrorHandler{}
client.ErrorHandlerRegistry.RegisterHandler("smtp.qq.com", "QUIT", qqMailQuitErrorHandler)
Socials: go-mail on Mastodon | #go-mail on Discord | #go-mail on Slack