github.com/opentofu/opentofu@v1.7.1/internal/states/statefile/diagnostics.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package statefile 7 8 import ( 9 "encoding/json" 10 "fmt" 11 12 "github.com/opentofu/opentofu/internal/tfdiags" 13 ) 14 15 const invalidFormat = "Invalid state file format" 16 17 // jsonUnmarshalDiags is a helper that translates errors returned from 18 // json.Unmarshal into hopefully-more-helpful diagnostics messages. 19 func jsonUnmarshalDiags(err error) tfdiags.Diagnostics { 20 var diags tfdiags.Diagnostics 21 if err == nil { 22 return diags 23 } 24 25 switch tErr := err.(type) { 26 case *json.SyntaxError: 27 // We've usually already successfully parsed a source file as JSON at 28 // least once before we'd use jsonUnmarshalDiags with it (to sniff 29 // the version number) so this particular error should not appear much 30 // in practice. 31 diags = diags.Append(tfdiags.Sourceless( 32 tfdiags.Error, 33 invalidFormat, 34 fmt.Sprintf("The state file could not be parsed as JSON: syntax error at byte offset %d.", tErr.Offset), 35 )) 36 case *json.UnmarshalTypeError: 37 // This is likely to be the most common area, describing a 38 // non-conformance between the file and the expected file format 39 // at a semantic level. 40 if tErr.Field != "" { 41 diags = diags.Append(tfdiags.Sourceless( 42 tfdiags.Error, 43 invalidFormat, 44 fmt.Sprintf("The state file field %q has invalid value %s", tErr.Field, tErr.Value), 45 )) 46 break 47 } else { 48 // Without a field name, we can't really say anything helpful. 49 diags = diags.Append(tfdiags.Sourceless( 50 tfdiags.Error, 51 invalidFormat, 52 "The state file does not conform to the expected JSON data structure.", 53 )) 54 } 55 default: 56 // Fallback for all other types of errors. This can happen only for 57 // custom UnmarshalJSON implementations, so should be encountered 58 // only rarely. 59 diags = diags.Append(tfdiags.Sourceless( 60 tfdiags.Error, 61 invalidFormat, 62 fmt.Sprintf("The state file does not conform to the expected JSON data structure: %s.", err.Error()), 63 )) 64 } 65 66 return diags 67 }