mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
fix error not shown on send message endpoint. Fix error sometimes shown as context cancelled instead of error due to early cancel before body was read
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
@@ -870,8 +870,10 @@ func (c *Campaign) SendEmailByCampaignRecipientID(g *gin.Context) {
|
||||
}
|
||||
// send message (email or API depending on campaign template configuration)
|
||||
err := c.CampaignService.SendEmailByCampaignRecipientID(g.Request.Context(), session, id)
|
||||
// handle responses
|
||||
if ok := c.handleErrors(g, err); !ok {
|
||||
// handle responses - sending failures are expected (invalid recipient email etc)
|
||||
// so return as bad request instead of internal server error
|
||||
if err != nil {
|
||||
c.Response.BadRequestMessage(g, err.Error())
|
||||
return
|
||||
}
|
||||
c.Response.OK(g, gin.H{})
|
||||
|
||||
@@ -752,8 +752,8 @@ func (a *APISender) sendRequest(
|
||||
apiRequestBody *apiRequestBody,
|
||||
) (*http.Response, func(), error) {
|
||||
// prepare request
|
||||
reqCtx, reqCancel := context.WithTimeout(ctx, 3*time.Second)
|
||||
defer reqCancel()
|
||||
reqCtx, reqCancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
// context must stay alive until response body is read
|
||||
if apiRequestBody == nil {
|
||||
apiRequestBody = bytes.NewBuffer([]byte{})
|
||||
}
|
||||
@@ -764,6 +764,7 @@ func (a *APISender) sendRequest(
|
||||
apiRequestBody,
|
||||
)
|
||||
if err != nil {
|
||||
reqCancel()
|
||||
return nil, func() {}, errs.Wrap(err)
|
||||
}
|
||||
// TODO these headers should be enrished with template variables like {{.FirstName}} or etc
|
||||
@@ -774,10 +775,16 @@ func (a *APISender) sendRequest(
|
||||
a.Logger.Debugw("sending request", "URL", apiRequestURL.String())
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
reqCancel()
|
||||
return nil, func() {}, errs.Wrap(err)
|
||||
}
|
||||
// #nosec
|
||||
return resp, func() { resp.Body.Close() }, nil
|
||||
// return cleanup function that closes body and cancels context
|
||||
// context must not be canceled until after response body is read
|
||||
// otherwise io.ReadAll(resp.Body) can fail with "context canceled"
|
||||
return resp, func() {
|
||||
resp.Body.Close()
|
||||
reqCancel()
|
||||
}, nil
|
||||
}
|
||||
|
||||
type apiRequestURL = bytes.Buffer
|
||||
|
||||
@@ -2274,7 +2274,7 @@ func (c *Campaign) saveSendingResult(
|
||||
if sendError != nil {
|
||||
data, err = vo.NewOptionalString1MB(sendError.Error())
|
||||
if err != nil {
|
||||
return errs.Wrap(fmt.Errorf("failed to create data: %s", err))
|
||||
return errs.Wrap(fmt.Errorf("failed to create reason: %s", err))
|
||||
}
|
||||
}
|
||||
campaignID := campaignRecipient.CampaignID.MustGet()
|
||||
@@ -3331,7 +3331,9 @@ func (c *Campaign) SendEmailByCampaignRecipientID(
|
||||
// send the email using existing logic from sendCampaignMessages
|
||||
err = c.sendSingleCampaignMessage(ctx, session, &campaignID, campaignRecipient)
|
||||
if err != nil {
|
||||
c.Logger.Errorw("failed to send campaign message", "error", err)
|
||||
// the failure is already logged in the campaign event with reason
|
||||
c.Logger.Warnw("failed to send campaign message", "reason", err)
|
||||
// don't wrap error, return as-is so controller can handle it as bad request
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -3467,6 +3469,11 @@ func (c *Campaign) sendSingleCampaignMessage(
|
||||
return errs.Wrap(saveErr)
|
||||
}
|
||||
|
||||
// if there was a sending error, log it as info since it's expected (e.g., invalid recipient)
|
||||
if err != nil {
|
||||
c.Logger.Infow("campaign message delivery failed", "reason", err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user