mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-02-01 22:47:40 +00:00
fix(migration): return proper error message when request fails
Related to https://github.com/go-vikunja/vikunja/issues/1788
This commit is contained in:
@@ -20,6 +20,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"net/http"
|
||||
@@ -92,9 +94,19 @@ func DoPostWithHeaders(url string, form url.Values, headers map[string]string) (
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Don't retry on last attempt
|
||||
// Return error on last attempt if still getting 5xx
|
||||
if attempt == maxRetries-1 {
|
||||
return resp, nil
|
||||
bodyBytes, readErr := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
|
||||
// Re-create the body so the caller can still read it if needed
|
||||
resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
|
||||
if readErr != nil {
|
||||
return resp, fmt.Errorf("request failed after %d attempts with status code %d (could not read response body: %w)", maxRetries, resp.StatusCode, readErr)
|
||||
}
|
||||
|
||||
return resp, fmt.Errorf("request failed after %d attempts with status code %d: %s", maxRetries, resp.StatusCode, string(bodyBytes))
|
||||
}
|
||||
|
||||
// Close the body before retrying
|
||||
@@ -108,5 +120,5 @@ func DoPostWithHeaders(url string, form url.Values, headers map[string]string) (
|
||||
time.Sleep(delay + jitter)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
return nil, fmt.Errorf("request failed after %d attempts", maxRetries)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
@@ -53,17 +54,25 @@ func TestDoPostWithHeaders_RetriesOn500(t *testing.T) {
|
||||
|
||||
func TestDoPostWithHeaders_GivesUpAfter3Retries(t *testing.T) {
|
||||
var attempts atomic.Int32
|
||||
expectedBody := "Internal Server Error: database connection failed"
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
attempts.Add(1)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write([]byte(expectedBody))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
form := url.Values{"key": {"value"}}
|
||||
resp, err := DoPostWithHeaders(server.URL, form, map[string]string{})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
if err == nil {
|
||||
t.Fatal("expected error after exhausted retries, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), expectedBody) {
|
||||
t.Errorf("expected error message to contain response body %q, got: %s", expectedBody, err.Error())
|
||||
}
|
||||
if resp == nil {
|
||||
t.Fatal("expected response to be returned with error, got nil")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusInternalServerError {
|
||||
|
||||
Reference in New Issue
Block a user