2020-01-03 23:01:14 +01:00
|
|
|
---
|
2021-11-23 00:57:25 +01:00
|
|
|
layout: "language"
|
|
|
|
page_title: "try - Functions - Configuration Language"
|
|
|
|
sidebar_current: "docs-funcs-conversion-try"
|
2020-01-03 23:01:14 +01:00
|
|
|
description: |-
|
|
|
|
The try function tries to evaluate a sequence of expressions given as
|
|
|
|
arguments and returns the result of the first one that does not produce
|
|
|
|
any errors.
|
|
|
|
---
|
|
|
|
|
|
|
|
# `try` Function
|
|
|
|
|
|
|
|
`try` evaluates all of its argument expressions in turn and returns the result
|
|
|
|
of the first one that does not produce any errors.
|
|
|
|
|
|
|
|
This is a special function that is able to catch errors produced when evaluating
|
|
|
|
its arguments, which is particularly useful when working with complex data
|
|
|
|
structures whose shape is not well-known at implementation time.
|
|
|
|
|
|
|
|
For example, if some data is retrieved from an external system in JSON or YAML
|
|
|
|
format and then decoded, the result may have attributes that are not guaranteed
|
|
|
|
to be set. We can use `try` to produce a normalized data structure which has
|
|
|
|
a predictable type that can therefore be used more conveniently elsewhere in
|
|
|
|
the configuration:
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
locals {
|
2020-06-16 09:56:03 +02:00
|
|
|
raw_value = yamldecode(file("${path.module}/example.yaml"))
|
2020-01-03 23:01:14 +01:00
|
|
|
normalized_value = {
|
|
|
|
name = tostring(try(local.raw_value.name, null))
|
|
|
|
groups = try(local.raw_value.groups, [])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
With the above local value expressions, configuration elsewhere in the module
|
|
|
|
can refer to `local.normalized_value` attributes without the need to repeatedly
|
|
|
|
check for and handle absent attributes that would otherwise produce errors.
|
|
|
|
|
|
|
|
We can also use `try` to deal with situations where a value might be provided
|
|
|
|
in two different forms, allowing us to normalize to the most general form:
|
|
|
|
|
|
|
|
```hcl
|
|
|
|
variable "example" {
|
|
|
|
type = any
|
|
|
|
}
|
|
|
|
|
|
|
|
locals {
|
|
|
|
example = try(
|
|
|
|
[tostring(var.example)],
|
|
|
|
tolist(var.example),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The above permits `var.example` to be either a list or a single string. If it's
|
|
|
|
a single string then it'll be normalized to a single-element list containing
|
|
|
|
that string, again allowing expressions elsewhere in the configuration to just
|
|
|
|
assume that `local.example` is always a list.
|
|
|
|
|
|
|
|
This second example contains two expressions that can both potentially fail.
|
|
|
|
For example, if `var.example` were set to `{}` then it could be converted to
|
|
|
|
neither a string nor a list. If `try` exhausts all of the given expressions
|
|
|
|
without any succeeding, it will return an error describing all of the problems
|
|
|
|
it encountered.
|
|
|
|
|
|
|
|
We strongly suggest using `try` only in special local values whose expressions
|
|
|
|
perform normalization, so that the error handling is confined to a single
|
|
|
|
location in the module and the rest of the module can just use straightforward
|
|
|
|
references to the normalized structure and thus be more readable for future
|
|
|
|
maintainers.
|
|
|
|
|
|
|
|
The `try` function can only catch and handle _dynamic_ errors resulting from
|
|
|
|
access to data that isn't known until runtime. It will not catch errors
|
|
|
|
relating to expressions that can be proven to be invalid for any input, such
|
|
|
|
as a malformed resource reference.
|
|
|
|
|
|
|
|
~> **Warning:** The `try` function is intended only for concise testing of the
|
|
|
|
presence of and types of object attributes. Although it can technically accept
|
|
|
|
any sort of expression, we recommend using it only with simple attribute
|
|
|
|
references and type conversion functions as shown in the examples above.
|
|
|
|
Overuse of `try` to suppress errors will lead to a configuration that is hard
|
|
|
|
to understand and maintain.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
```
|
|
|
|
> local.foo
|
|
|
|
{
|
|
|
|
"bar" = "baz"
|
|
|
|
}
|
|
|
|
> try(local.foo.bar, "fallback")
|
|
|
|
baz
|
|
|
|
> try(local.foo.boop, "fallback")
|
|
|
|
fallback
|
|
|
|
```
|
|
|
|
|
|
|
|
The `try` function will _not_ catch errors relating to constructs that are
|
2021-06-18 17:59:56 +02:00
|
|
|
probably invalid even before dynamic expression evaluation, such as a malformed
|
2020-01-03 23:01:14 +01:00
|
|
|
reference or a reference to a top-level object that has not been declared:
|
|
|
|
|
|
|
|
```
|
|
|
|
> try(local.nonexist, "fallback")
|
|
|
|
|
|
|
|
Error: Reference to undeclared local value
|
|
|
|
|
|
|
|
A local value with the name "nonexist" has not been declared.
|
|
|
|
```
|
|
|
|
|
|
|
|
## Related Functions
|
|
|
|
|
2021-11-23 00:57:25 +01:00
|
|
|
* [`can`](./can.html), which tries evaluating an expression and returns a
|
2020-01-03 23:01:14 +01:00
|
|
|
boolean value indicating whether it succeeded.
|