Skip to content

Commit f659568

Browse files
committed
fix: correctly close SMTP message and await response
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent 4672849 commit f659568

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

coderd/notifications/dispatch/smtp.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ func (s *SMTPHandler) dispatch(subject, htmlBody, plainBody, to string) Delivery
183183
if err != nil {
184184
return true, xerrors.Errorf("message transmission: %w", err)
185185
}
186-
defer message.Close()
187186

188187
// Create message headers.
189188
msg := &bytes.Buffer{}
@@ -251,6 +250,10 @@ func (s *SMTPHandler) dispatch(subject, htmlBody, plainBody, to string) Delivery
251250
return false, xerrors.Errorf("write body buffer: %w", err)
252251
}
253252

253+
if err = message.Close(); err != nil {
254+
return true, xerrors.Errorf("delivery failure: %w", err)
255+
}
256+
254257
// Returning false, nil indicates successful send (i.e. non-retryable non-error)
255258
return false, nil
256259
}

coderd/notifications/dispatch/smtp_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func TestSMTP(t *testing.T) {
6262
expectedErr string
6363
retryable bool
6464
useTLS bool
65+
failOnDataFn func() error
6566
}{
6667
/**
6768
* LOGIN auth mechanism
@@ -381,6 +382,21 @@ func TestSMTP(t *testing.T) {
381382
toAddrs: []string{to},
382383
expectedAuthMeth: sasl.Plain,
383384
},
385+
/**
386+
* Other errors
387+
*/
388+
{
389+
name: "Rejected on DATA",
390+
cfg: codersdk.NotificationsEmailConfig{
391+
Hello: hello,
392+
From: from,
393+
},
394+
failOnDataFn: func() error {
395+
return &smtp.SMTPError{Code: 501, EnhancedCode: smtp.EnhancedCode{5, 5, 4}, Message: "Rejected!"}
396+
},
397+
expectedErr: "SMTP error 501: Rejected!",
398+
retryable: true,
399+
},
384400
}
385401

386402
// nolint:paralleltest // Reinitialization is not required as of Go v1.22.
@@ -398,6 +414,8 @@ func TestSMTP(t *testing.T) {
398414
AcceptedIdentity: tc.cfg.Auth.Identity.String(),
399415
AcceptedUsername: username,
400416
AcceptedPassword: password,
417+
418+
FailOnDataFn: tc.failOnDataFn,
401419
})
402420

403421
// Create a mock SMTP server which conditionally listens for plain or TLS connections.

coderd/notifications/dispatch/smtp_util_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var (
2424
type Config struct {
2525
AuthMechanisms []string
2626
AcceptedIdentity, AcceptedUsername, AcceptedPassword string
27+
FailOnDataFn func() error
2728
}
2829

2930
type Message struct {
@@ -147,6 +148,10 @@ func (s *Session) Data(r io.Reader) error {
147148
return err
148149
}
149150

151+
if s.backend.cfg.FailOnDataFn != nil {
152+
return s.backend.cfg.FailOnDataFn()
153+
}
154+
150155
s.backend.lastMsg.Contents = string(b)
151156

152157
return nil

0 commit comments

Comments
 (0)