From 0262be65ef1c29b7f48befd427ab1cb23c89ca5f Mon Sep 17 00:00:00 2001 From: Maxime Delporte Date: Thu, 4 Dec 2025 14:12:55 +0100 Subject: [PATCH] Sending background emails. --- cmd/api/helpers.go | 21 +++++++++++++++++++-- cmd/api/users.go | 20 ++++++++++++-------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/cmd/api/helpers.go b/cmd/api/helpers.go index 52fb1f6..ddfe6da 100644 --- a/cmd/api/helpers.go +++ b/cmd/api/helpers.go @@ -4,13 +4,14 @@ import ( "encoding/json" "errors" "fmt" - "github.com/julienschmidt/httprouter" - "greenlight.craftr.fr/internal/validator" "io" "net/http" "net/url" "strconv" "strings" + + "github.com/julienschmidt/httprouter" + "greenlight.craftr.fr/internal/validator" ) /* @@ -204,3 +205,19 @@ func (app *application) readInt(qs url.Values, key string, defaultValue int, v * // Otherwise, return the converted integer value return i } + +// Background: accepts an arbitrary function as a parameter +func (app *application) background(fn func()) { + // Launch a background goroutine + go func() { + // recover any panic. + defer func() { + if err := recover(); err != nil { + app.logger.Error("%v", err) + } + }() + + // Execute the arbitrary function that we passed as the parameter + fn() + }() +} diff --git a/cmd/api/users.go b/cmd/api/users.go index 1d3fce1..e5102eb 100644 --- a/cmd/api/users.go +++ b/cmd/api/users.go @@ -59,15 +59,19 @@ func (app *application) registerUserHandler(w http.ResponseWriter, r *http.Reque return } - // Call the Send() method on our Mail, passing in the user's email address, name of the template file, and the User struct containing the new user's data. - err = app.mailer.Send(user.Email, "user_welcome.tmpl", user) - if err != nil { - app.serverErrorResponse(w, r, err) - return - } + // Use the background helper to execute an anonymous function that send the welcome email + app.background(func() { + // Call the Send() method on our Mail, passing in the user's email address, name of the template file, and the User struct containing the new user's data. + err = app.mailer.Send(user.Email, "user_welcome.tmpl", user) + + if err != nil { + // Importantly, if there is an error sending the email, then we use the app.logger.Error() helper to manage it, instead of the app.serverErrorResponse() helper like before. + app.logger.Error(err.Error()) + } + }) - // Write a JSON response containing the user data along with a 201 Created status code - err = app.writeJSON(w, http.StatusCreated, envelope{"user": user}, nil) + // Not that we also change this to send the client a 202 Accepted status code. This status code indicates that the request has been accepted for processing, but the processing has not been completed. + err = app.writeJSON(w, http.StatusAccepted, envelope{"user": user}, nil) if err != nil { app.serverErrorResponse(w, r, err) }