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

jsondecode (and other internal functions) should display their inputs upon failure #26823

Open
richardj-bsquare opened this issue Nov 5, 2020 · 1 comment

Comments

@richardj-bsquare
Copy link

richardj-bsquare commented Nov 5, 2020

Current Terraform Version

0.13.5

...

Use-cases

If you are using functions such as (but not limited to) jsondecode within a for_each resource and one of the supplied values is erroneous, you cannot tell which supplied value is erroneous. in more complex scenarios than this contrived example, it can make finding the faulty values extremely tedious and time consuming.

example:

locals {
	json_string_map = { "good": "{}", "fine": "[]", "wrong":"", "incorrect": "{\"x\"}" }

	json_map = {
		for key,value in local.json_string_map:
	    key => jsondecode(value)
	}
}

actual output:

$terraform validate

Error: Error in function call

  on test.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: invalid character '}' after object key.


Error: Error in function call

  on test.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: EOF.

Attempted Solutions

Proposal

Upon error, dump the input parameters of the particular function failure; even better in this case would be to also dump the variables in scope (key,value).

Potential output:

$terraform validate

Error: Error in function call

  on test.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: invalid character '}' after object key. jsonencode called with value '{"x"}' 


Error: Error in function call

  on test.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: EOF. jsonencode called with value ''.

This would at least give the developer a clue.

References

@richardj-bsquare richardj-bsquare added enhancement new new issue not yet triaged labels Nov 5, 2020
@apparentlymart
Copy link
Member

Hi @richardj-bsquare! Thanks for this suggestion.

The way we typically solve this problem is for the error messages to systematically include either full values (for primitive types) or summaries (for complex types) of all of the external values that contributed to the expression that failed. We do it this way both to make it consistent and comprehensive and because the diagnostic printer is able to take into account when a particular value is marked as sensitive and thus omit it, which the various different functions would not necessarily handle correctly.

I tried something like what you shared here and saw an error message which includes such an annotation:

$ terraform plan

Error: Error in function call

  on jsonencode-fails.tf line 6, in output "example":
   6:   value = jsondecode(local.raw)
    |----------------
    | local.raw is "{"

Call to function "jsondecode" failed: EOF.
locals {
  raw = "{"
}

output "example" {
  value = jsondecode(local.raw)
}

However, when I tried your example exactly as you gave it, neither of the error messages included that annotation:

$ terraform plan

Error: Error in function call

  on jsonencode-fails.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: invalid character '}' after object key.


Error: Error in function call

  on jsonencode-fails.tf line 6, in locals:
   6: 	    key => jsondecode(value)

Call to function "jsondecode" failed: EOF.

With that said, I'd like to respond to this request by understanding why Terraform isn't reporting the value of value in your more complex situation. My initial theory is that it's because value belongs to a local scope created by the for expression and so perhaps the language runtime isn't handling that correctly, but from an initial read of the relevant code I wasn't able to quickly determine why that might be. (The EvalContext here should be the same one that was used to evaluate the arguments, and so it should include the value symbol.)

I won't have time to debug this further today, but hopefully what I've written here is useful to either future me or someone else who is motivated to work on this some more in the future.

Thanks again for pointing this out!

@pkolyvas pkolyvas removed the new new issue not yet triaged label Nov 9, 2020
@bflad bflad added the functions label Dec 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants