diff --git a/command/ota/upload.go b/command/ota/upload.go index fcb32267..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" @@ -101,9 +102,18 @@ 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 { - return err + if errors.Is(err, iot.ErrOtaAlreadyInProgress) { + conflictedOta = &otaapi.Ota{ + DeviceID: params.DeviceID, + Status: "Skipped", + ErrorReason: "OTA already in progress", + } + } else { + return err + } } // Try to get ota-id from API otaID, err := otapi.GetOtaLastStatusByDeviceID(params.DeviceID) @@ -111,7 +121,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..1ea50544 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -28,6 +28,8 @@ import ( "golang.org/x/oauth2" ) +var ErrOtaAlreadyInProgress = fmt.Errorf("ota 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 }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: