diff --git a/builtin/providers/test/resource.go b/builtin/providers/test/resource.go index c0e742acd..9aa384791 100644 --- a/builtin/providers/test/resource.go +++ b/builtin/providers/test/resource.go @@ -49,7 +49,6 @@ func testResource() *schema.Resource { "computed_read_only": { Type: schema.TypeString, Computed: true, - ForceNew: true, }, "computed_from_required": { Type: schema.TypeString, diff --git a/builtin/providers/test/resource_gh12183.go b/builtin/providers/test/resource_gh12183.go index 07f164de1..d67bcf755 100644 --- a/builtin/providers/test/resource_gh12183.go +++ b/builtin/providers/test/resource_gh12183.go @@ -47,7 +47,7 @@ func testResourceGH12183() *schema.Resource { func testResourceCreate_gh12183(d *schema.ResourceData, meta interface{}) error { d.SetId("testId") - return testResourceRead(d, meta) + return testResourceRead_gh12183(d, meta) } func testResourceRead_gh12183(d *schema.ResourceData, meta interface{}) error { diff --git a/helper/schema/resource_data.go b/helper/schema/resource_data.go index 15aa0b5d4..970dc7b99 100644 --- a/helper/schema/resource_data.go +++ b/helper/schema/resource_data.go @@ -35,6 +35,8 @@ type ResourceData struct { partialMap map[string]struct{} once sync.Once isNew bool + + panicOnError bool } // getResult is the internal structure that is generated when a Get @@ -184,7 +186,11 @@ func (d *ResourceData) Set(key string, value interface{}) error { } } - return d.setWriter.WriteField(strings.Split(key, "."), value) + err := d.setWriter.WriteField(strings.Split(key, "."), value) + if err != nil && d.panicOnError { + panic(err) + } + return err } // SetPartial adds the key to the final state output while diff --git a/helper/schema/resource_data_test.go b/helper/schema/resource_data_test.go index 09aefb8f1..9785f121f 100644 --- a/helper/schema/resource_data_test.go +++ b/helper/schema/resource_data_test.go @@ -3,6 +3,7 @@ package schema import ( "fmt" "math" + "os" "reflect" "testing" "time" @@ -2055,6 +2056,10 @@ func TestResourceDataSet(t *testing.T) { }, } + oldEnv := os.Getenv(PanicOnErr) + os.Setenv(PanicOnErr, "") + defer os.Setenv(PanicOnErr, oldEnv) + for i, tc := range cases { d, err := schemaMap(tc.Schema).Data(tc.State, tc.Diff) if err != nil { diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 903d71513..6cc71df51 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -25,6 +25,9 @@ import ( "github.com/mitchellh/mapstructure" ) +// Name of ENV variable which (if not empty) prefers panic over error +const PanicOnErr = "TF_SCHEMA_PANIC_ON_ERROR" + // type used for schema package context keys type contextKey string @@ -358,6 +361,13 @@ func (s *Schema) finalizeDiff( // schemaMap is a wrapper that adds nice functions on top of schemas. type schemaMap map[string]*Schema +func (m schemaMap) panicOnError() bool { + if os.Getenv(PanicOnErr) != "" { + return true + } + return false +} + // Data returns a ResourceData for the given schema, state, and diff. // // The diff is optional. @@ -365,9 +375,10 @@ func (m schemaMap) Data( s *terraform.InstanceState, d *terraform.InstanceDiff) (*ResourceData, error) { return &ResourceData{ - schema: m, - state: s, - diff: d, + schema: m, + state: s, + diff: d, + panicOnError: m.panicOnError(), }, nil } @@ -397,9 +408,10 @@ func (m schemaMap) Diff( } d := &ResourceData{ - schema: m, - state: s, - config: c, + schema: m, + state: s, + config: c, + panicOnError: m.panicOnError(), } for k, schema := range m {