Add missing error logs

This commit is contained in:
Kailash Nadh 2020-03-07 23:00:55 +05:30
parent 0a2d2d66be
commit 83b49df39d
6 changed files with 84 additions and 27 deletions

View File

@ -88,6 +88,7 @@ func handleGetCampaigns(c echo.Context) error {
err := app.Queries.QueryCampaigns.Select(&out.Results, id, pq.StringArray(status), query, pg.Offset, pg.Limit) err := app.Queries.QueryCampaigns.Select(&out.Results, id, pq.StringArray(status), query, pg.Offset, pg.Limit)
if err != nil { if err != nil {
app.Logger.Printf("error fetching campaigns: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaigns: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaigns: %s", pqErrMsg(err)))
} }
@ -112,6 +113,7 @@ func handleGetCampaigns(c echo.Context) error {
// Lazy load stats. // Lazy load stats.
if err := out.Results.LoadStats(app.Queries.GetCampaignStats); err != nil { if err := out.Results.LoadStats(app.Queries.GetCampaignStats); err != nil {
app.Logger.Printf("error fetching campaign stats: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign stats: %v", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign stats: %v", pqErrMsg(err)))
} }
@ -148,6 +150,7 @@ func handlePreviewCampaign(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.") return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
} }
app.Logger.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err)))
} }
@ -159,6 +162,7 @@ func handlePreviewCampaign(c echo.Context) error {
// There's no subscriber. Mock one. // There's no subscriber. Mock one.
sub = dummySubscriber sub = dummySubscriber
} else { } else {
app.Logger.Printf("error fetching subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err)))
} }
@ -170,6 +174,7 @@ func handlePreviewCampaign(c echo.Context) error {
} }
if err := camp.CompileTemplate(app.Manager.TemplateFuncs(camp)); err != nil { if err := camp.CompileTemplate(app.Manager.TemplateFuncs(camp)); err != nil {
app.Logger.Printf("error compiling template: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error compiling template: %v", err)) fmt.Sprintf("Error compiling template: %v", err))
} }
@ -177,6 +182,7 @@ func handlePreviewCampaign(c echo.Context) error {
// Render the message body. // Render the message body.
m := app.Manager.NewMessage(camp, &sub) m := app.Manager.NewMessage(camp, &sub)
if err := m.Render(); err != nil { if err := m.Render(); err != nil {
app.Logger.Printf("error rendering message: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error rendering message: %v", err)) fmt.Sprintf("Error rendering message: %v", err))
} }
@ -219,7 +225,7 @@ func handleCreateCampaign(c echo.Context) error {
uu, err := uuid.NewV4() uu, err := uuid.NewV4()
if err != nil { if err != nil {
app.Logger.Println("error generating UUID: %v", err) app.Logger.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID") return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID")
} }
@ -244,6 +250,7 @@ func handleCreateCampaign(c echo.Context) error {
"There aren't any subscribers in the target lists to create the campaign.") "There aren't any subscribers in the target lists to create the campaign.")
} }
app.Logger.Printf("error creating campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error creating campaign: %v", pqErrMsg(err))) fmt.Sprintf("Error creating campaign: %v", pqErrMsg(err)))
} }
@ -272,6 +279,7 @@ func handleUpdateCampaign(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.") return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
} }
app.Logger.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err)))
} }
@ -305,6 +313,7 @@ func handleUpdateCampaign(c echo.Context) error {
o.TemplateID, o.TemplateID,
o.ListIDs) o.ListIDs)
if err != nil { if err != nil {
app.Logger.Printf("error updating campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error updating campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error updating campaign: %s", pqErrMsg(err)))
} }
@ -333,6 +342,7 @@ func handleUpdateCampaignStatus(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.") return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
} }
app.Logger.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err)))
} }
@ -377,8 +387,9 @@ func handleUpdateCampaignStatus(c echo.Context) error {
res, err := app.Queries.UpdateCampaignStatus.Exec(cm.ID, o.Status) res, err := app.Queries.UpdateCampaignStatus.Exec(cm.ID, o.Status)
if err != nil { if err != nil {
app.Logger.Printf("error updating campaign status: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error updating campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error updating campaign status: %s", pqErrMsg(err)))
} }
if n, _ := res.RowsAffected(); n == 0 { if n, _ := res.RowsAffected(); n == 0 {
@ -406,6 +417,7 @@ func handleDeleteCampaign(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.") return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
} }
app.Logger.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err)))
} }
@ -418,6 +430,7 @@ func handleDeleteCampaign(c echo.Context) error {
} }
if _, err := app.Queries.DeleteCampaign.Exec(cm.ID); err != nil { if _, err := app.Queries.DeleteCampaign.Exec(cm.ID); err != nil {
app.Logger.Printf("error deleting campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error deleting campaign: %v", pqErrMsg(err))) fmt.Sprintf("Error deleting campaign: %v", pqErrMsg(err)))
} }
@ -437,6 +450,7 @@ func handleGetRunningCampaignStats(c echo.Context) error {
return c.JSON(http.StatusOK, okResp{[]struct{}{}}) return c.JSON(http.StatusOK, okResp{[]struct{}{}})
} }
app.Logger.Printf("error fetching campaign stats: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign stats: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign stats: %s", pqErrMsg(err)))
} else if len(out) == 0 { } else if len(out) == 0 {
@ -496,6 +510,7 @@ func handleTestCampaign(c echo.Context) error {
} }
var subs models.Subscribers var subs models.Subscribers
if err := app.Queries.GetSubscribersByEmails.Select(&subs, req.SubscriberEmails); err != nil { if err := app.Queries.GetSubscribersByEmails.Select(&subs, req.SubscriberEmails); err != nil {
app.Logger.Printf("error fetching subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching subscribers: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching subscribers: %s", pqErrMsg(err)))
} else if len(subs) == 0 { } else if len(subs) == 0 {
@ -508,6 +523,8 @@ func handleTestCampaign(c echo.Context) error {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.") return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
} }
app.Logger.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching campaign: %s", pqErrMsg(err)))
} }
@ -522,7 +539,8 @@ func handleTestCampaign(c echo.Context) error {
for _, s := range subs { for _, s := range subs {
sub := s sub := s
if err := sendTestMessage(&sub, &camp, app); err != nil { if err := sendTestMessage(&sub, &camp, app); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Error sending test: %v", err)) return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error sending test: %v", err))
} }
} }
@ -532,12 +550,14 @@ func handleTestCampaign(c echo.Context) error {
// sendTestMessage takes a campaign and a subsriber and sends out a sample campaign message. // sendTestMessage takes a campaign and a subsriber and sends out a sample campaign message.
func sendTestMessage(sub *models.Subscriber, camp *models.Campaign, app *App) error { func sendTestMessage(sub *models.Subscriber, camp *models.Campaign, app *App) error {
if err := camp.CompileTemplate(app.Manager.TemplateFuncs(camp)); err != nil { if err := camp.CompileTemplate(app.Manager.TemplateFuncs(camp)); err != nil {
app.Logger.Printf("error compiling template: %v", err)
return fmt.Errorf("Error compiling template: %v", err) return fmt.Errorf("Error compiling template: %v", err)
} }
// Render the message body. // Render the message body.
m := app.Manager.NewMessage(camp, sub) m := app.Manager.NewMessage(camp, sub)
if err := m.Render(); err != nil { if err := m.Render(); err != nil {
app.Logger.Printf("error rendering message: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error rendering message: %v", err)) fmt.Sprintf("Error rendering message: %v", err))
} }

View File

@ -39,6 +39,7 @@ func handleGetLists(c echo.Context) error {
err := app.Queries.GetLists.Select(&out.Results, listID, pg.Offset, pg.Limit) err := app.Queries.GetLists.Select(&out.Results, listID, pg.Offset, pg.Limit)
if err != nil { if err != nil {
app.Logger.Printf("error fetching lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching lists: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching lists: %s", pqErrMsg(err)))
} }
@ -64,7 +65,6 @@ func handleGetLists(c echo.Context) error {
out.Total = out.Results[0].Total out.Total = out.Results[0].Total
out.Page = pg.Page out.Page = pg.Page
out.PerPage = pg.PerPage out.PerPage = pg.PerPage
return c.JSON(http.StatusOK, okResp{out}) return c.JSON(http.StatusOK, okResp{out})
} }
@ -87,7 +87,7 @@ func handleCreateList(c echo.Context) error {
uu, err := uuid.NewV4() uu, err := uuid.NewV4()
if err != nil { if err != nil {
app.Logger.Println("error generating UUID: %v", err) app.Logger.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID") return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID")
} }
@ -100,6 +100,7 @@ func handleCreateList(c echo.Context) error {
o.Type, o.Type,
o.Optin, o.Optin,
pq.StringArray(normalizeTags(o.Tags))); err != nil { pq.StringArray(normalizeTags(o.Tags))); err != nil {
app.Logger.Printf("error creating list: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error creating list: %s", pqErrMsg(err))) fmt.Sprintf("Error creating list: %s", pqErrMsg(err)))
} }
@ -127,8 +128,10 @@ func handleUpdateList(c echo.Context) error {
return err return err
} }
res, err := app.Queries.UpdateList.Exec(id, o.Name, o.Type, o.Optin, pq.StringArray(normalizeTags(o.Tags))) res, err := app.Queries.UpdateList.Exec(id,
o.Name, o.Type, o.Optin, pq.StringArray(normalizeTags(o.Tags)))
if err != nil { if err != nil {
app.Logger.Printf("error updating list: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error updating list: %s", pqErrMsg(err))) fmt.Sprintf("Error updating list: %s", pqErrMsg(err)))
} }
@ -163,8 +166,9 @@ func handleDeleteLists(c echo.Context) error {
} }
if _, err := app.Queries.DeleteLists.Exec(ids); err != nil { if _, err := app.Queries.DeleteLists.Exec(ids); err != nil {
app.Logger.Printf("error deleting lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Delete failed: %v", err)) fmt.Sprintf("Error deleting: %v", err))
} }
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})

View File

@ -10,13 +10,19 @@ import (
"github.com/labstack/echo" "github.com/labstack/echo"
) )
var imageMimes = []string{"image/jpg", "image/jpeg", "image/png", "image/svg", "image/gif"}
const ( const (
thumbPrefix = "thumb_" thumbPrefix = "thumb_"
thumbnailSize = 90 thumbnailSize = 90
) )
// imageMimes is the list of image types allowed to be uploaded.
var imageMimes = []string{
"image/jpg",
"image/jpeg",
"image/png",
"image/svg",
"image/gif"}
// handleUploadMedia handles media file uploads. // handleUploadMedia handles media file uploads.
func handleUploadMedia(c echo.Context) error { func handleUploadMedia(c echo.Context) error {
var ( var (
@ -28,15 +34,17 @@ func handleUploadMedia(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Invalid file uploaded: %v", err)) fmt.Sprintf("Invalid file uploaded: %v", err))
} }
// Validate MIME type with the list of allowed types. // Validate MIME type with the list of allowed types.
var typ = file.Header.Get("Content-type") var typ = file.Header.Get("Content-type")
ok := validateMIME(typ, imageMimes) if ok := validateMIME(typ, imageMimes); !ok {
if !ok {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Unsupported file type (%s) uploaded.", typ)) fmt.Sprintf("Unsupported file type (%s) uploaded.", typ))
} }
// Generate filename // Generate filename
fName := generateFileName(file.Filename) fName := generateFileName(file.Filename)
// Read file contents in memory // Read file contents in memory
src, err := file.Open() src, err := file.Open()
if err != nil { if err != nil {
@ -44,9 +52,11 @@ func handleUploadMedia(c echo.Context) error {
fmt.Sprintf("Error reading file: %s", err)) fmt.Sprintf("Error reading file: %s", err))
} }
defer src.Close() defer src.Close()
// Upload the file. // Upload the file.
fName, err = app.Media.Put(fName, typ, src) fName, err = app.Media.Put(fName, typ, src)
if err != nil { if err != nil {
app.Logger.Printf("error uploading file: %v", err)
cleanUp = true cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error uploading file: %s", err)) fmt.Sprintf("Error uploading file: %s", err))
@ -65,27 +75,30 @@ func handleUploadMedia(c echo.Context) error {
thumbFile, err := createThumbnail(file) thumbFile, err := createThumbnail(file)
if err != nil { if err != nil {
cleanUp = true cleanUp = true
app.Logger.Printf("error resizing image: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error opening image for resizing: %s", err)) fmt.Sprintf("Error resizing image: %s", err))
} }
// Upload thumbnail. // Upload thumbnail.
thumbfName, err := app.Media.Put(thumbPrefix+fName, typ, thumbFile) thumbfName, err := app.Media.Put(thumbPrefix+fName, typ, thumbFile)
if err != nil { if err != nil {
cleanUp = true cleanUp = true
app.Logger.Printf("error saving thumbnail: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error saving thumbnail: %s", err)) fmt.Sprintf("Error saving thumbnail: %s", err))
} }
uu, err := uuid.NewV4() uu, err := uuid.NewV4()
if err != nil { if err != nil {
app.Logger.Println("error generating UUID: %v", err) app.Logger.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID") return echo.NewHTTPError(http.StatusInternalServerError, "Error generating UUID")
} }
// Write to the DB. // Write to the DB.
if _, err := app.Queries.InsertMedia.Exec(uu, fName, thumbfName, 0, 0); err != nil { if _, err := app.Queries.InsertMedia.Exec(uu, fName, thumbfName, 0, 0); err != nil {
cleanUp = true cleanUp = true
app.Logger.Printf("error inserting uploaded file to db: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error saving uploaded file to db: %s", pqErrMsg(err))) fmt.Sprintf("Error saving uploaded file to db: %s", pqErrMsg(err)))
} }
@ -131,6 +144,5 @@ func handleDeleteMedia(c echo.Context) error {
app.Media.Delete(m.Filename) app.Media.Delete(m.Filename)
app.Media.Delete(thumbPrefix + m.Filename) app.Media.Delete(thumbPrefix + m.Filename)
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"database/sql"
"html/template" "html/template"
"image" "image"
"image/png" "image/png"
@ -113,6 +114,7 @@ func handleSubscriptionPage(c echo.Context) error {
makeMsgTpl("Error", "", makeMsgTpl("Error", "",
`Error processing request. Please retry.`)) `Error processing request. Please retry.`))
} }
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,
makeMsgTpl("Unsubscribed", "", makeMsgTpl("Unsubscribed", "",
`You have been successfully unsubscribed.`)) `You have been successfully unsubscribed.`))
@ -232,7 +234,10 @@ func handleLinkRedirect(c echo.Context) error {
var url string var url string
if err := app.Queries.RegisterLinkClick.Get(&url, linkUUID, campUUID, subUUID); err != nil { if err := app.Queries.RegisterLinkClick.Get(&url, linkUUID, campUUID, subUUID); err != nil {
app.Logger.Printf("error fetching redirect link: %s", err) if err != sql.ErrNoRows {
app.Logger.Printf("error fetching redirect link: %s", err)
}
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl("Error opening link", "", makeMsgTpl("Error opening link", "",
"There was an error opening the link. Please try later.")) "There was an error opening the link. Please try later."))
@ -269,8 +274,7 @@ func handleSelfExportSubscriberData(c echo.Context) error {
// Is export allowed? // Is export allowed?
if !app.Constants.Privacy.AllowExport { if !app.Constants.Privacy.AllowExport {
return c.Render(http.StatusBadRequest, tplMessage, return c.Render(http.StatusBadRequest, tplMessage,
makeMsgTpl("Invalid request", "", makeMsgTpl("Invalid request", "", "The feature is not available."))
"The feature is not available."))
} }
// Get the subscriber's data. A single query that gets the profile, // Get the subscriber's data. A single query that gets the profile,
@ -287,7 +291,8 @@ func handleSelfExportSubscriberData(c echo.Context) error {
// Send the data out to the subscriber as an atachment. // Send the data out to the subscriber as an atachment.
var msg bytes.Buffer var msg bytes.Buffer
if err := app.NotifTpls.ExecuteTemplate(&msg, notifSubscriberData, data); err != nil { if err := app.NotifTpls.ExecuteTemplate(&msg, notifSubscriberData, data); err != nil {
app.Logger.Printf("error compiling notification template '%s': %v", notifSubscriberData, err) app.Logger.Printf("error compiling notification template '%s': %v",
notifSubscriberData, err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl("Error preparing data", "", makeMsgTpl("Error preparing data", "",
"There was an error preparing your data. Please try later.")) "There was an error preparing your data. Please try later."))

View File

@ -178,7 +178,6 @@ func (im *Importer) getStatus() string {
im.RLock() im.RLock()
status := im.status.Status status := im.status.Status
im.RUnlock() im.RUnlock()
return status return status
} }
@ -190,7 +189,6 @@ func (im *Importer) isDone() bool {
s = false s = false
} }
im.RUnlock() im.RUnlock()
return s return s
} }

View File

@ -76,6 +76,7 @@ func handleGetSubscriber(c echo.Context) error {
err := app.Queries.GetSubscriber.Select(&out, id, nil) err := app.Queries.GetSubscriber.Select(&out, id, nil)
if err != nil { if err != nil {
app.Logger.Printf("error fetching subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err)))
} }
@ -83,7 +84,9 @@ func handleGetSubscriber(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Subscriber not found.") return echo.NewHTTPError(http.StatusBadRequest, "Subscriber not found.")
} }
if err := out.LoadLists(app.Queries.GetSubscriberListsLazy); err != nil { if err := out.LoadLists(app.Queries.GetSubscriberListsLazy); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Error loading lists for subscriber.") app.Logger.Printf("error loading subscriber lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError,
"Error loading subscriber lists.")
} }
return c.JSON(http.StatusOK, okResp{out[0]}) return c.JSON(http.StatusOK, okResp{out[0]})
@ -117,11 +120,13 @@ func handleQuerySubscribers(c echo.Context) error {
} }
stmt := fmt.Sprintf(app.Queries.QuerySubscribers, cond) stmt := fmt.Sprintf(app.Queries.QuerySubscribers, cond)
// Create a readonly transaction to prevent mutations. // Create a readonly transaction to prevent mutations.
tx, err := app.DB.BeginTxx(context.Background(), &sql.TxOptions{ReadOnly: true}) tx, err := app.DB.BeginTxx(context.Background(), &sql.TxOptions{ReadOnly: true})
if err != nil { if err != nil {
app.Logger.Printf("error preparing subscriber query: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error preparing query: %v", pqErrMsg(err))) fmt.Sprintf("Error preparing subscriber query: %v", pqErrMsg(err)))
} }
defer tx.Rollback() defer tx.Rollback()
@ -133,6 +138,7 @@ func handleQuerySubscribers(c echo.Context) error {
// Lazy load lists for each subscriber. // Lazy load lists for each subscriber.
if err := out.Results.LoadLists(app.Queries.GetSubscriberListsLazy); err != nil { if err := out.Results.LoadLists(app.Queries.GetSubscriberListsLazy); err != nil {
app.Logger.Printf("error fetching subscriber lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching subscriber lists: %v", pqErrMsg(err))) fmt.Sprintf("Error fetching subscriber lists: %v", pqErrMsg(err)))
} }
@ -211,10 +217,10 @@ func handleUpdateSubscriber(c echo.Context) error {
req.Status, req.Status,
req.Attribs, req.Attribs,
req.Lists) req.Lists)
if err != nil { if err != nil {
app.Logger.Printf("error updating subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Update failed: %v", pqErrMsg(err))) fmt.Sprintf("Error updating subscriber: %v", pqErrMsg(err)))
} }
return handleGetSubscriber(c) return handleGetSubscriber(c)
@ -235,6 +241,7 @@ func handleGetSubscriberSendOptin(c echo.Context) error {
// Fetch the subscriber. // Fetch the subscriber.
err := app.Queries.GetSubscriber.Select(&out, id, nil) err := app.Queries.GetSubscriber.Select(&out, id, nil)
if err != nil { if err != nil {
app.Logger.Printf("error fetching subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err))) fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err)))
} }
@ -281,6 +288,7 @@ func handleBlacklistSubscribers(c echo.Context) error {
} }
if _, err := app.Queries.BlacklistSubscribers.Exec(IDs); err != nil { if _, err := app.Queries.BlacklistSubscribers.Exec(IDs); err != nil {
app.Logger.Printf("error blacklisting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error blacklisting: %v", err)) fmt.Sprintf("Error blacklisting: %v", err))
} }
@ -337,6 +345,7 @@ func handleManageSubscriberLists(c echo.Context) error {
} }
if err != nil { if err != nil {
app.Logger.Printf("error updating subscriptions: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error processing lists: %v", err)) fmt.Sprintf("Error processing lists: %v", err))
} }
@ -375,8 +384,9 @@ func handleDeleteSubscribers(c echo.Context) error {
} }
if _, err := app.Queries.DeleteSubscribers.Exec(IDs, nil); err != nil { if _, err := app.Queries.DeleteSubscribers.Exec(IDs, nil); err != nil {
app.Logger.Printf("error deleting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error deleting: %v", err)) fmt.Sprintf("Error deleting subscribers: %v", err))
} }
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})
@ -398,6 +408,7 @@ func handleDeleteSubscribersByQuery(c echo.Context) error {
app.Queries.DeleteSubscribersByQuery, app.Queries.DeleteSubscribersByQuery,
req.ListIDs, app.DB) req.ListIDs, app.DB)
if err != nil { if err != nil {
app.Logger.Printf("error querying subscribers: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error: %v", err)) fmt.Sprintf("Error: %v", err))
} }
@ -421,6 +432,7 @@ func handleBlacklistSubscribersByQuery(c echo.Context) error {
app.Queries.BlacklistSubscribersByQuery, app.Queries.BlacklistSubscribersByQuery,
req.ListIDs, app.DB) req.ListIDs, app.DB)
if err != nil { if err != nil {
app.Logger.Printf("error blacklisting subscribers: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error: %v", err)) fmt.Sprintf("Error: %v", err))
} }
@ -456,8 +468,10 @@ func handleManageSubscriberListsByQuery(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Invalid action.") return echo.NewHTTPError(http.StatusBadRequest, "Invalid action.")
} }
err := app.Queries.execSubscriberQueryTpl(sanitizeSQLExp(req.Query), stmt, req.ListIDs, app.DB, req.TargetListIDs) err := app.Queries.execSubscriberQueryTpl(sanitizeSQLExp(req.Query),
stmt, req.ListIDs, app.DB, req.TargetListIDs)
if err != nil { if err != nil {
app.Logger.Printf("error updating subscriptions: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
fmt.Sprintf("Error: %v", err)) fmt.Sprintf("Error: %v", err))
} }
@ -514,8 +528,10 @@ func insertSubscriber(req subimporter.SubReq, app *App) (int, error) {
if pqErr, ok := err.(*pq.Error); ok && pqErr.Constraint == "subscribers_email_key" { if pqErr, ok := err.(*pq.Error); ok && pqErr.Constraint == "subscribers_email_key" {
return 0, echo.NewHTTPError(http.StatusBadRequest, "The e-mail already exists.") return 0, echo.NewHTTPError(http.StatusBadRequest, "The e-mail already exists.")
} }
app.Logger.Printf("error inserting subscriber: %v", err)
return 0, echo.NewHTTPError(http.StatusInternalServerError, return 0, echo.NewHTTPError(http.StatusInternalServerError,
fmt.Sprintf("Error creating subscriber: %v", err)) fmt.Sprintf("Error inserting subscriber: %v", err))
} }
// If the lists are double-optins, send confirmation e-mails. // If the lists are double-optins, send confirmation e-mails.
@ -541,6 +557,7 @@ func exportSubscriberData(id int64, subUUID string, exportables map[string]bool,
uu = subUUID uu = subUUID
} }
if err := app.Queries.ExportSubscriberData.Get(&data, id, uu); err != nil { if err := app.Queries.ExportSubscriberData.Get(&data, id, uu); err != nil {
app.Logger.Printf("error fetching subscriber export data: %v", err)
return data, nil, err return data, nil, err
} }
@ -561,6 +578,7 @@ func exportSubscriberData(id int64, subUUID string, exportables map[string]bool,
// Marshal the data into an indented payload. // Marshal the data into an indented payload.
b, err := json.MarshalIndent(data, "", " ") b, err := json.MarshalIndent(data, "", " ")
if err != nil { if err != nil {
app.Logger.Printf("error marshalling subscriber export data: %v", err)
return data, nil, err return data, nil, err
} }
return data, b, nil return data, b, nil