Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: standardise error handling #539

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions internal/common/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright Splunk, Inc.
// SPDX-License-Identifier: MPL-2.0

package common

import (
"context"
"net/http"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/signalfx/signalfx-go"

tfext "github.com/splunk-terraform/terraform-provider-signalfx/internal/tfextension"
)

// OnError handles the general case when the signalfx api returns
// an error, and it uses that information to determine what needs to happen.
// This will ensure that the state is cleaned up given the error condition.
// To help simplify error handling, it will always return the error provided.
func OnError(ctx context.Context, err error, data *schema.ResourceData) error {
re, ok := signalfx.AsResponseError(err)
if !ok {
// Not a response error, pass it back
return err
}
switch re.Code() {
case http.StatusNotFound:
tflog.Info(ctx, "Resource has been removed externally, removing from state", tfext.NewLogFields().
Field("route", re.Route()),
)
// Clear the id from the state when 404 is returned.
data.SetId("")
case http.StatusUnauthorized:
tflog.Error(ctx, "Token is not authorized", tfext.NewLogFields().
Field("route", re.Route()).
Field("code", re.Code()).
Field("details", re.Details()),
)

Check warning on line 39 in internal/common/error.go

View check run for this annotation

Codecov / codecov/patch

internal/common/error.go#L28-L39

Added lines #L28 - L39 were not covered by tests
default:
tflog.Debug(ctx, "Issue trying to work with the API", tfext.NewLogFields().
Field("route", re.Route()).
Field("code", re.Code()).
Field("details", re.Details()),
)
}
return err
}
54 changes: 54 additions & 0 deletions internal/common/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright Splunk, Inc.
// SPDX-License-Identifier: MPL-2.0

package common

import (
"context"
"errors"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/signalfx/signalfx-go"
"github.com/stretchr/testify/assert"
)

func TestOnError(t *testing.T) {
t.Parallel()

for _, tc := range []struct {
name string
err error
expect string
}{
{
name: "no error provided",
err: nil,
expect: "id",
},
{
name: "not a response rror",
err: errors.New("derp"),
expect: "id",
},
{
name: "uncatalogue response error",
err: &signalfx.ResponseError{},
expect: "id",
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

data := schema.TestResourceDataRaw(
t,
map[string]*schema.Schema{},
map[string]any{},
)
data.SetId("id")

assert.ErrorIs(t, tc.err, OnError(context.Background(), tc.err, data), "Must return the same error")
assert.Equal(t, tc.expect, data.Id(), "Must have the expected id")
})
}
}
10 changes: 6 additions & 4 deletions internal/definition/detector/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/signalfx/signalfx-go/detector"

"github.com/splunk-terraform/terraform-provider-signalfx/internal/common"
pmeta "github.com/splunk-terraform/terraform-provider-signalfx/internal/providermeta"
tfext "github.com/splunk-terraform/terraform-provider-signalfx/internal/tfextension"
)
Expand Down Expand Up @@ -63,7 +64,7 @@ func resourceCreate(ctx context.Context, data *schema.ResourceData, meta any) (i
ParentDetectorId: dt.ParentDetectorId,
DetectorOrigin: dt.DetectorOrigin,
})
if err != nil {
if common.OnError(ctx, err, data) != nil {
return tfext.AsErrorDiagnostics(err)
}

Expand All @@ -88,7 +89,7 @@ func resourceRead(ctx context.Context, data *schema.ResourceData, meta any) (iss
}

dt, err := client.GetDetector(ctx, data.Id())
if err != nil {
if common.OnError(ctx, err, data) != nil {
return tfext.AsErrorDiagnostics(err)
}

Expand Down Expand Up @@ -133,7 +134,7 @@ func resourceUpdate(ctx context.Context, data *schema.ResourceData, meta any) (i
ParentDetectorId: dt.ParentDetectorId,
DetectorOrigin: dt.DetectorOrigin,
})
if err != nil {
if common.OnError(ctx, err, data) != nil {
return tfext.AsErrorDiagnostics(err)
}

Expand All @@ -154,5 +155,6 @@ func resourceDelete(ctx context.Context, data *schema.ResourceData, meta any) di
if err != nil {
return tfext.AsErrorDiagnostics(err)
}
return tfext.AsErrorDiagnostics(client.DeleteDetector(ctx, data.Id()))
err = common.OnError(ctx, client.DeleteDetector(ctx, data.Id()), data)
return tfext.AsErrorDiagnostics(err)
}
12 changes: 8 additions & 4 deletions internal/definition/team/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/signalfx/signalfx-go/team"

"github.com/splunk-terraform/terraform-provider-signalfx/internal/common"
pmeta "github.com/splunk-terraform/terraform-provider-signalfx/internal/providermeta"
)

Expand Down Expand Up @@ -49,7 +50,7 @@ func newResourceCreate() schema.CreateContextFunc {
Members: payload.Members,
NotificationLists: payload.NotificationLists,
})
if err != nil {
if common.OnError(ctx, err, rd) != nil {
return diag.FromErr(err)
}

Expand All @@ -73,9 +74,10 @@ func newResourceRead() schema.ReadContextFunc {
}

tm, err := client.GetTeam(ctx, rd.Id())
if err != nil {
if common.OnError(ctx, err, rd) != nil {
return diag.FromErr(err)
}

tflog.Debug(ctx, "Successfully fetched team data")

if err := rd.Set("url", pmeta.LoadApplicationURL(ctx, meta, AppPath, tm.Id)); err != nil {
Expand Down Expand Up @@ -104,7 +106,7 @@ func newResourceUpdate() schema.UpdateContextFunc {
Members: payload.Members,
NotificationLists: payload.NotificationLists,
})
if err != nil {
if common.OnError(ctx, err, rd) != nil {
return diag.FromErr(err)
}

Expand All @@ -128,6 +130,8 @@ func newResourceDelete() schema.DeleteContextFunc {
"team-id": rd.Id(),
})

return diag.FromErr(client.DeleteTeam(ctx, rd.Id()))
err = common.OnError(ctx, client.DeleteTeam(ctx, rd.Id()), rd)

return diag.FromErr(err)
}
}
Loading