Skip to content

Commit

Permalink
fix: properly close HTTP responses after sending each email
Browse files Browse the repository at this point in the history
This change extracts per-email sending logic into a helper function
for which proper resource closing can be performed. Previously it
invoke defer res.Body.Close in a for-loop but Go's specifications
and operations dictate that the defer will only be invoked when
the surrounding function is returning or panicking: this means then
that if very many emails are being sent, that risks potential
resource exhaustion because so many connections won't be closed yet
nor can they be garbage collected.

Fixes cds-snc#13
  • Loading branch information
odeke-em committed Mar 20, 2024
1 parent b893964 commit 748e20b
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions notify_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,35 @@ func sendEmail(client *NotifyClient, email *NotifyEmail) error {
req.Header.Set("Content-Type", contentType)
req.Header.Set("Authorization", fmt.Sprintf("ApiKey-v1 %s", client.ApiKey))

resp, err := client.Client.Do(req)

if err != nil {
log.Error().Msgf("Error sending email: %s", err)
if err := doSendEmail(client.Client, req); err != nil {
return err
}
}

return nil
}

defer resp.Body.Close()
func doSendEmail(client *http.Client, req *http.Request) error {
resp, err := client.Do(req)
if err != nil {
log.Error().Msgf("Error sending email: %s", err)
return err
}
defer resp.Body.Close()

if resp.StatusCode != 201 {
log.Error().Msgf("Unexpected status code: %d", resp.StatusCode)
respbody, err := io.ReadAll(resp.Body)
if resp.StatusCode == 201 {
return nil
}

if err != nil {
log.Error().Msgf("Error reading response body: %s", err)
return err
}
log.Error().Msgf("Response: %s", respbody)
// A non-201 status code so craft the error.
log.Error().Msgf("Unexpected status code: %d", resp.StatusCode)
respbody, err := io.ReadAll(resp.Body)

return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
if err != nil {
log.Error().Msgf("Error reading response body: %s", err)
return err
}
log.Error().Msgf("Response: %s", respbody)

return nil
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

0 comments on commit 748e20b

Please sign in to comment.