From a32424ec6a321e03d3a90e64cb95c7c545d7f47c Mon Sep 17 00:00:00 2001 From: Paolo Calao Date: Mon, 30 Aug 2021 14:49:06 +0200 Subject: [PATCH] Improve iot client errors --- internal/iot/client.go | 24 ++++++++++-------------- internal/iot/error.go | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 internal/iot/error.go diff --git a/internal/iot/client.go b/internal/iot/client.go index b7955f46..327afe31 100644 --- a/internal/iot/client.go +++ b/internal/iot/client.go @@ -2,7 +2,6 @@ package iot import ( "context" - "encoding/json" "fmt" "github.com/antihax/optional" @@ -50,7 +49,7 @@ func (cl *client) AddDevice(fqbn, name, serial, dType string) (string, error) { } dev, _, err := cl.api.DevicesV2Api.DevicesV2Create(cl.ctx, payload) if err != nil { - err = fmt.Errorf("creating device, %w", err) + err = fmt.Errorf("creating device, %w", errorDetail(err)) return "", err } return dev.Id, nil @@ -61,7 +60,7 @@ func (cl *client) AddDevice(fqbn, name, serial, dType string) (string, error) { func (cl *client) DeleteDevice(id string) error { _, err := cl.api.DevicesV2Api.DevicesV2Delete(cl.ctx, id) if err != nil { - err = fmt.Errorf("deleting device: %w", err) + err = fmt.Errorf("deleting device: %w", errorDetail(err)) return err } return nil @@ -72,7 +71,7 @@ func (cl *client) DeleteDevice(id string) error { func (cl *client) ListDevices() ([]iotclient.ArduinoDevicev2, error) { devices, _, err := cl.api.DevicesV2Api.DevicesV2List(cl.ctx, nil) if err != nil { - err = fmt.Errorf("listing devices: %w", err) + err = fmt.Errorf("listing devices: %w", errorDetail(err)) return nil, err } return devices, nil @@ -89,7 +88,7 @@ func (cl *client) AddCertificate(id, csr string) (*iotclient.ArduinoCompressedv2 newCert, _, err := cl.api.DevicesV2CertsApi.DevicesV2CertsCreate(cl.ctx, id, cert) if err != nil { - err = fmt.Errorf("creating certificate, %w", err) + err = fmt.Errorf("creating certificate, %w", errorDetail(err)) return nil, err } @@ -99,12 +98,9 @@ func (cl *client) AddCertificate(id, csr string) (*iotclient.ArduinoCompressedv2 // AddThing adds a new thing on Arduino IoT Cloud. func (cl *client) AddThing(thing *iotclient.Thing, force bool) (string, error) { opt := &iotclient.ThingsV2CreateOpts{Force: optional.NewBool(force)} - newThing, resp, err := cl.api.ThingsV2Api.ThingsV2Create(cl.ctx, *thing, opt) + newThing, _, err := cl.api.ThingsV2Api.ThingsV2Create(cl.ctx, *thing, opt) if err != nil { - var respObj map[string]interface{} - json.NewDecoder(resp.Body).Decode(&respObj) - resp.Body.Close() - return "", fmt.Errorf("%s: %s: %v", "adding new thing", err, respObj) + return "", fmt.Errorf("%s: %w", "adding new thing", errorDetail(err)) } return newThing.Id, nil } @@ -114,7 +110,7 @@ func (cl *client) UpdateThing(id string, thing *iotclient.Thing, force bool) err opt := &iotclient.ThingsV2UpdateOpts{Force: optional.NewBool(force)} _, _, err := cl.api.ThingsV2Api.ThingsV2Update(cl.ctx, id, *thing, opt) if err != nil { - return fmt.Errorf("%s: %v", "updating thing", err) + return fmt.Errorf("%s: %v", "updating thing", errorDetail(err)) } return nil } @@ -123,7 +119,7 @@ func (cl *client) UpdateThing(id string, thing *iotclient.Thing, force bool) err func (cl *client) DeleteThing(id string) error { _, err := cl.api.ThingsV2Api.ThingsV2Delete(cl.ctx, id, nil) if err != nil { - err = fmt.Errorf("deleting thing: %w", err) + err = fmt.Errorf("deleting thing: %w", errorDetail(err)) return err } return nil @@ -134,7 +130,7 @@ func (cl *client) DeleteThing(id string) error { func (cl *client) GetThing(id string) (*iotclient.ArduinoThing, error) { thing, _, err := cl.api.ThingsV2Api.ThingsV2Show(cl.ctx, id, nil) if err != nil { - err = fmt.Errorf("retrieving thing, %w", err) + err = fmt.Errorf("retrieving thing, %w", errorDetail(err)) return nil, err } return &thing, nil @@ -155,7 +151,7 @@ func (cl *client) ListThings(ids []string, device *string, props bool) ([]iotcli things, _, err := cl.api.ThingsV2Api.ThingsV2List(cl.ctx, opts) if err != nil { - err = fmt.Errorf("retrieving things, %w", err) + err = fmt.Errorf("retrieving things, %w", errorDetail(err)) return nil, err } return things, nil diff --git a/internal/iot/error.go b/internal/iot/error.go new file mode 100644 index 00000000..dc7b4759 --- /dev/null +++ b/internal/iot/error.go @@ -0,0 +1,23 @@ +package iot + +import ( + "fmt" + + iotclient "github.com/arduino/iot-client-go" +) + +// errorDetail takes a generic iot-client-go error +// and tries to return a more detailed error. +func errorDetail(err error) error { + apiErr, ok := err.(iotclient.GenericOpenAPIError) + if !ok { + return err + } + + modErr, ok := apiErr.Model().(iotclient.ModelError) + if !ok { + return err + } + + return fmt.Errorf("%w: %s", err, modErr.Detail) +}