refactor(notifier): improve smtp errors (#3646)
parent
394dafde01
commit
c9cfc8afa9
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -185,14 +186,17 @@ func (n *SMTPNotifier) dial() (err error) {
|
||||||
n.log.Infof("Notifier SMTP client using submissions port 465. Make sure the mail server you are connecting to is configured for submissions and not SMTPS.")
|
n.log.Infof("Notifier SMTP client using submissions port 465. Make sure the mail server you are connecting to is configured for submissions and not SMTPS.")
|
||||||
|
|
||||||
conn, err = tls.DialWithDialer(dialer, "tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port), n.tlsConfig)
|
conn, err = tls.DialWithDialer(dialer, "tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port), n.tlsConfig)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
conn, err = dialer.Dial("tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port))
|
conn, err = dialer.Dial("tcp", fmt.Sprintf("%s:%d", n.configuration.Host, n.configuration.Port))
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
break
|
||||||
|
case errors.Is(err, io.EOF):
|
||||||
|
return fmt.Errorf("received %w error: this error often occurs due to network errors such as a firewall, network policies, or closed ports which may be due to smtp service not running or an incorrect port specified in configuration", err)
|
||||||
|
default:
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err = smtp.NewClient(conn, n.configuration.Host)
|
client, err = smtp.NewClient(conn, n.configuration.Host)
|
||||||
|
@ -217,30 +221,30 @@ func (n *SMTPNotifier) cleanup() {
|
||||||
|
|
||||||
// StartupCheck implements the startup check provider interface.
|
// StartupCheck implements the startup check provider interface.
|
||||||
func (n *SMTPNotifier) StartupCheck() (err error) {
|
func (n *SMTPNotifier) StartupCheck() (err error) {
|
||||||
if err := n.dial(); err != nil {
|
if err = n.dial(); err != nil {
|
||||||
return err
|
return fmt.Errorf("error dialing the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer n.cleanup()
|
defer n.cleanup()
|
||||||
|
|
||||||
if err := n.client.Hello(n.configuration.Identifier); err != nil {
|
if err = n.client.Hello(n.configuration.Identifier); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing HELO/EHLO with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.startTLS(); err != nil {
|
if err = n.startTLS(); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing STARTTLS with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.auth(); err != nil {
|
if err = n.auth(); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing AUTH with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.client.Mail(n.configuration.Sender.Address); err != nil {
|
if err = n.client.Mail(n.configuration.Sender.Address); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing MAIL FROM with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.client.Rcpt(n.configuration.StartupCheckAddress); err != nil {
|
if err = n.client.Rcpt(n.configuration.StartupCheckAddress); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing RCPT with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return n.client.Reset()
|
return n.client.Reset()
|
||||||
|
@ -250,39 +254,41 @@ func (n *SMTPNotifier) StartupCheck() (err error) {
|
||||||
func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
func (n *SMTPNotifier) Send(recipient, title, body, htmlBody string) error {
|
||||||
subject := strings.ReplaceAll(n.configuration.Subject, "{title}", title)
|
subject := strings.ReplaceAll(n.configuration.Subject, "{title}", title)
|
||||||
|
|
||||||
if err := n.dial(); err != nil {
|
var err error
|
||||||
return err
|
|
||||||
|
if err = n.dial(); err != nil {
|
||||||
|
return fmt.Errorf("error dialing the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always execute QUIT at the end once we're connected.
|
// Always execute QUIT at the end once we're connected.
|
||||||
defer n.cleanup()
|
defer n.cleanup()
|
||||||
|
|
||||||
if err := n.client.Hello(n.configuration.Identifier); err != nil {
|
if err = n.client.Hello(n.configuration.Identifier); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing HELO/EHLO with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start TLS and then Authenticate.
|
if err = n.startTLS(); err != nil {
|
||||||
if err := n.startTLS(); err != nil {
|
return fmt.Errorf("error performing STARTTLS with the smtp server: %w", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.auth(); err != nil {
|
if err = n.auth(); err != nil {
|
||||||
return err
|
return fmt.Errorf("error performing AUTH with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the sender and recipient first.
|
if err = n.client.Mail(n.configuration.Sender.Address); err != nil {
|
||||||
if err := n.client.Mail(n.configuration.Sender.Address); err != nil {
|
|
||||||
n.log.Debugf("Notifier SMTP failed while sending MAIL FROM (using sender) with error: %s", err)
|
n.log.Debugf("Notifier SMTP failed while sending MAIL FROM (using sender) with error: %s", err)
|
||||||
return err
|
|
||||||
|
return fmt.Errorf("error performing MAIL FROM with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.client.Rcpt(recipient); err != nil {
|
if err = n.client.Rcpt(n.configuration.StartupCheckAddress); err != nil {
|
||||||
n.log.Debugf("Notifier SMTP failed while sending RCPT TO (using recipient) with error: %s", err)
|
n.log.Debugf("Notifier SMTP failed while sending RCPT TO (using recipient) with error: %s", err)
|
||||||
return err
|
|
||||||
|
return fmt.Errorf("error performing RCPT with the smtp server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compose and send the email body to the server.
|
// Compose and send the email body to the server.
|
||||||
if err := n.compose(recipient, subject, body, htmlBody); err != nil {
|
if err = n.compose(recipient, subject, body, htmlBody); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue