mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-07-28 00:28:55 +00:00
refactor(services): return *UpstreamError from decodeResponse
Replace the ad-hoc fmt.Errorf non-2xx branch with apierr.ParseGarage so decodeResponse now returns a typed *apierr.UpstreamError on error. Update two admin_test.go tests that string-matched the old error shape to assert UpstreamError fields (HTTPStatus, Message) instead.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"Noooste/garage-ui/internal/apierr"
|
||||
"Noooste/garage-ui/internal/config"
|
||||
"Noooste/garage-ui/internal/models"
|
||||
"Noooste/garage-ui/pkg/utils"
|
||||
@@ -63,13 +64,14 @@ func (s *GarageAdminService) doRequest(ctx context.Context, method, path string,
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// decodeResponse decodes a JSON response into the target structure
|
||||
// decodeResponse decodes a JSON response into the target structure. Non-2xx
|
||||
// responses are converted to *apierr.UpstreamError (Source="garage") so the
|
||||
// handler layer can map them to the correct API error code and HTTP status.
|
||||
func decodeResponse(resp *azuretls.Response, target interface{}) error {
|
||||
defer resp.RawBody.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
bodyBytes, _ := io.ReadAll(resp.RawBody)
|
||||
return fmt.Errorf("API returned status %d: %s", resp.StatusCode, string(bodyBytes))
|
||||
if err := apierr.ParseGarage(resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if target != nil {
|
||||
@@ -77,7 +79,6 @@ func decodeResponse(resp *azuretls.Response, target interface{}) error {
|
||||
return fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"Noooste/garage-ui/internal/apierr"
|
||||
"Noooste/garage-ui/internal/config"
|
||||
"Noooste/garage-ui/internal/models"
|
||||
)
|
||||
@@ -103,8 +105,12 @@ func TestHealthCheck_Non2xxReturnsError(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("expected error for 503, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "503") {
|
||||
t.Errorf("error should mention status code, got %v", err)
|
||||
var ue *apierr.UpstreamError
|
||||
if !errors.As(err, &ue) {
|
||||
t.Fatalf("expected *apierr.UpstreamError, got %T (%v)", err, err)
|
||||
}
|
||||
if ue.HTTPStatus != http.StatusServiceUnavailable {
|
||||
t.Errorf("HTTPStatus = %d, want %d", ue.HTTPStatus, http.StatusServiceUnavailable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,8 +515,15 @@ func TestDoRequest_Non2xxBodyEchoedInError(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("expected error for 400, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "400") || !strings.Contains(err.Error(), "bad request") {
|
||||
t.Errorf("error %v should contain 400 and the response body", err)
|
||||
var ue *apierr.UpstreamError
|
||||
if !errors.As(err, &ue) {
|
||||
t.Fatalf("expected *apierr.UpstreamError, got %T (%v)", err, err)
|
||||
}
|
||||
if ue.HTTPStatus != http.StatusBadRequest {
|
||||
t.Errorf("HTTPStatus = %d, want %d", ue.HTTPStatus, http.StatusBadRequest)
|
||||
}
|
||||
if !strings.Contains(ue.Message, "bad request") {
|
||||
t.Errorf("Message = %q, want it to contain the response body", ue.Message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user