From 496ddcf4897f264824f7a2edb19d0f92db54a286 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Thu, 2 May 2024 18:20:53 +0200 Subject: [PATCH 1/2] Print conflicted OTA in report --- command/ota/upload.go | 17 ++++++++++++++++- internal/iot/client.go | 11 ++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/command/ota/upload.go b/command/ota/upload.go index fcb32267..cc89b45a 100644 --- a/command/ota/upload.go +++ b/command/ota/upload.go @@ -101,8 +101,16 @@ func Upload(ctx context.Context, params *UploadParams, cred *config.Credentials) expiration = otaDeferredExpirationMins } + var conflictedOta *otaapi.Ota err = iotClient.DeviceOTA(ctx, params.DeviceID, file, expiration) if err != nil { + if err == iot.ErrOtaAlreadyInProgress { + conflictedOta = &otaapi.Ota{ + DeviceID: params.DeviceID, + Status: "Failed", + ErrorReason: "OTA already in progress", + } + } return err } // Try to get ota-id from API @@ -111,7 +119,14 @@ func Upload(ctx context.Context, params *UploadParams, cred *config.Credentials) return err } if otaID != nil && len(otaID.Ota) > 0 { - feedback.PrintResult(otaID.Ota[0]) + if conflictedOta != nil { + toPrint := otaapi.OtaStatusList{ + Ota: []otaapi.Ota{*conflictedOta, otaID.Ota[0]}, + } + feedback.PrintResult(toPrint) + } else { + feedback.PrintResult(otaID.Ota[0]) + } } return nil diff --git a/internal/iot/client.go b/internal/iot/client.go index 55170caa..fe407264 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -28,6 +28,8 @@ import ( "golang.org/x/oauth2" ) +var ErrOtaAlreadyInProgress = fmt.Errorf("already in progress") + // Client can perform actions on Arduino IoT Cloud. type Client struct { api *iotclient.APIClient @@ -196,9 +198,12 @@ func (cl *Client) DeviceOTA(ctx context.Context, id string, file *os.File, expir Async: optional.NewBool(true), } resp, err := cl.api.DevicesV2OtaApi.DevicesV2OtaUpload(ctx, id, file, opt) - if err != nil && resp.StatusCode != 409 { // 409 (Conflict) is the status code for an already existing OTA for the same SHA/device, so ignoring it. - err = fmt.Errorf("uploading device ota: %w", errorDetail(err)) - return err + if err != nil { + // 409 (Conflict) is the status code for an already existing OTA in progress for the same device. Handling it in a different way. + if resp.StatusCode == 409 { + return ErrOtaAlreadyInProgress + } + return fmt.Errorf("uploading device ota: %w", errorDetail(err)) } return nil } From 047ad6509324f95057fc99997a3ef259f6a41167 Mon Sep 17 00:00:00 2001 From: Marco Colombo Date: Fri, 3 May 2024 10:05:01 +0200 Subject: [PATCH 2/2] Refactored print error --- command/ota/upload.go | 8 +++++--- internal/iot/client.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/command/ota/upload.go b/command/ota/upload.go index cc89b45a..a41cf462 100644 --- a/command/ota/upload.go +++ b/command/ota/upload.go @@ -19,6 +19,7 @@ package ota import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -104,14 +105,15 @@ func Upload(ctx context.Context, params *UploadParams, cred *config.Credentials) var conflictedOta *otaapi.Ota err = iotClient.DeviceOTA(ctx, params.DeviceID, file, expiration) if err != nil { - if err == iot.ErrOtaAlreadyInProgress { + if errors.Is(err, iot.ErrOtaAlreadyInProgress) { conflictedOta = &otaapi.Ota{ DeviceID: params.DeviceID, - Status: "Failed", + Status: "Skipped", ErrorReason: "OTA already in progress", } + } else { + return err } - return err } // Try to get ota-id from API otaID, err := otapi.GetOtaLastStatusByDeviceID(params.DeviceID) diff --git a/internal/iot/client.go b/internal/iot/client.go index fe407264..1ea50544 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -28,7 +28,7 @@ import ( "golang.org/x/oauth2" ) -var ErrOtaAlreadyInProgress = fmt.Errorf("already in progress") +var ErrOtaAlreadyInProgress = fmt.Errorf("ota already in progress") // Client can perform actions on Arduino IoT Cloud. type Client struct {