feat(sdk): improved error messages

This commit is contained in:
Waldemar 2025-09-25 15:32:07 +02:00
parent 28ac61f38a
commit 1bd9105b07
3 changed files with 43 additions and 23 deletions

View file

@ -7,6 +7,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"net/http" "net/http"
sdkhttp "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/internal/http" sdkhttp "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/internal/http"
@ -195,9 +196,9 @@ func (c *Client) getTransport() *sdkhttp.Transport {
return sdkhttp.NewTransport( return sdkhttp.NewTransport(
sdkhttp.RetryOptions{ sdkhttp.RetryOptions{
MaxRetries: c.RetryOpts.MaxRetries, MaxRetries: c.RetryOpts.MaxRetries,
InitialDelay: c.RetryOpts.InitialDelay, InitialDelay: c.RetryOpts.InitialDelay,
MaxDelay: c.RetryOpts.MaxDelay, MaxDelay: c.RetryOpts.MaxDelay,
Multiplier: c.RetryOpts.Multiplier, Multiplier: c.RetryOpts.Multiplier,
RetryableHTTPStatusCodes: c.RetryOpts.RetryableHTTPStatusCodes, RetryableHTTPStatusCodes: c.RetryOpts.RetryableHTTPStatusCodes,
}, },
c.AuthProvider, c.AuthProvider,
@ -207,8 +208,22 @@ func (c *Client) getTransport() *sdkhttp.Transport {
// handleErrorResponse creates an appropriate error from HTTP error response // handleErrorResponse creates an appropriate error from HTTP error response
func (c *Client) handleErrorResponse(resp *http.Response, operation string) error { func (c *Client) handleErrorResponse(resp *http.Response, operation string) error {
messages := []string{
fmt.Sprintf("%s failed with status %d", operation, resp.StatusCode),
}
bodyBytes := []byte{}
if resp.Body != nil {
defer resp.Body.Close()
bodyBytes, _ = io.ReadAll(resp.Body)
messages = append(messages, string(bodyBytes))
}
return &APIError{ return &APIError{
StatusCode: resp.StatusCode, StatusCode: resp.StatusCode,
Messages: []string{fmt.Sprintf("%s failed with status %d", operation, resp.StatusCode)}, Messages: messages,
Body: bodyBytes,
} }
} }

View file

@ -3,7 +3,11 @@
package client package client
import "time" import (
"encoding/json"
"fmt"
"time"
)
// Message interface for types that can provide error messages // Message interface for types that can provide error messages
type Message interface { type Message interface {
@ -79,16 +83,16 @@ type AppInstance struct {
// Cloudlet represents edge infrastructure // Cloudlet represents edge infrastructure
type Cloudlet struct { type Cloudlet struct {
msg `json:",inline"` msg `json:",inline"`
Key CloudletKey `json:"key"` Key CloudletKey `json:"key"`
Location Location `json:"location"` Location Location `json:"location"`
IpSupport string `json:"ip_support,omitempty"` IpSupport string `json:"ip_support,omitempty"`
NumDynamicIps int32 `json:"num_dynamic_ips,omitempty"` NumDynamicIps int32 `json:"num_dynamic_ips,omitempty"`
State string `json:"state,omitempty"` State string `json:"state,omitempty"`
Flavor Flavor `json:"flavor,omitempty"` Flavor Flavor `json:"flavor,omitempty"`
PhysicalName string `json:"physical_name,omitempty"` PhysicalName string `json:"physical_name,omitempty"`
Region string `json:"region,omitempty"` Region string `json:"region,omitempty"`
NotifySrvAddr string `json:"notify_srv_addr,omitempty"` NotifySrvAddr string `json:"notify_srv_addr,omitempty"`
} }
// Location represents geographical coordinates // Location represents geographical coordinates
@ -181,10 +185,11 @@ type APIError struct {
} }
func (e *APIError) Error() string { func (e *APIError) Error() string {
if len(e.Messages) > 0 { jsonErr, err := json.Marshal(e)
return e.Messages[0] if err != nil {
return fmt.Sprintf("API error: %v", err)
} }
return "API error" return fmt.Sprintf("API error: %s", jsonErr)
} }
// Filter types for querying // Filter types for querying
@ -209,7 +214,7 @@ type CloudletFilter struct {
// CloudletManifest represents cloudlet deployment manifest // CloudletManifest represents cloudlet deployment manifest
type CloudletManifest struct { type CloudletManifest struct {
Manifest string `json:"manifest"` Manifest string `json:"manifest"`
LastModified time.Time `json:"last_modified,omitempty"` LastModified time.Time `json:"last_modified,omitempty"`
} }
@ -218,4 +223,4 @@ type CloudletResourceUsage struct {
CloudletKey CloudletKey `json:"cloudlet_key"` CloudletKey CloudletKey `json:"cloudlet_key"`
Region string `json:"region"` Region string `json:"region"`
Usage map[string]interface{} `json:"usage"` Usage map[string]interface{} `json:"usage"`
} }

View file

@ -55,7 +55,7 @@ func main() {
Name: "my-edge-app", Name: "my-edge-app",
Version: "1.0.0", Version: "1.0.0",
}, },
Deployment: "kubernetes", Deployment: "docker",
ImageType: "ImageTypeDocker", ImageType: "ImageTypeDocker",
ImagePath: "nginx:latest", ImagePath: "nginx:latest",
DefaultFlavor: client.Flavor{Name: "EU.small"}, DefaultFlavor: client.Flavor{Name: "EU.small"},
@ -80,7 +80,7 @@ func demonstrateAppLifecycle(ctx context.Context, edgeClient *client.Client, inp
// Step 1: Create the application // Step 1: Create the application
fmt.Println("\n1. Creating application...") fmt.Println("\n1. Creating application...")
if err := edgeClient.CreateApp(ctx, input); err != nil { if err := edgeClient.CreateApp(ctx, input); err != nil {
return fmt.Errorf("failed to create app: %w", err) return fmt.Errorf("failed to create app: %+v", err)
} }
fmt.Printf("✅ App created: %s/%s v%s\n", appKey.Organization, appKey.Name, appKey.Version) fmt.Printf("✅ App created: %s/%s v%s\n", appKey.Organization, appKey.Name, appKey.Version)