fix(webhook): close the response body when the callback returns an error status

This commit is contained in:
Julien Neuhart
2026-09-07 17:49:01 +02:00
parent c21ceacd4b
commit e1e0a80883

View File

@@ -143,13 +143,12 @@ func (c client) send(ctx context.Context, body io.Reader, headers map[string]str
return fmt.Errorf("send '%s' request to '%s': %w", method, url, err) return fmt.Errorf("send '%s' request to '%s': %w", method, url, err)
} }
if resp.StatusCode >= http.StatusBadRequest { // Registered before the status check below. [retryablehttp.Client.Do] hands
err := fmt.Errorf("send '%s' request to '%s': got status: '%s'", method, url, resp.Status) // back a live body for a status it does not retry, which is every 4xx but
span.RecordError(err) // 429, so returning early without closing it strands the connection and the
span.SetStatus(codes.Error, err.Error()) // transport goroutines that serve it for the lifetime of the process. The
return err // transport is built per delivery in [gotenberg.NewOutboundHttpClient], so
} // nothing reclaims it later either.
defer func() { defer func() {
err := resp.Body.Close() err := resp.Body.Close()
if err != nil { if err != nil {
@@ -157,6 +156,13 @@ func (c client) send(ctx context.Context, body io.Reader, headers map[string]str
} }
}() }()
if resp.StatusCode >= http.StatusBadRequest {
err := fmt.Errorf("send '%s' request to '%s': got status: '%s'", method, url, resp.Status)
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
// Last piece for calculating the latency. // Last piece for calculating the latency.
finishTime := time.Now() finishTime := time.Now()