try
函数
try
依次评估其所有参数表达式,并返回第一个不产生任何错误的表达式的结果。
这是一个特殊函数,能够捕获评估其参数时产生的错误,这在处理结构不确定的复杂数据结构时尤其有用,因为这些数据结构的形状在实现时可能未知。
例如,如果从外部系统以 JSON 或 YAML 格式检索某些数据,然后对其进行解码,则结果可能具有并非一定设置的属性。我们可以使用 try
生成一个规范化的数据结构,该结构具有可预测的类型,因此可以在配置中的其他地方更方便地使用。
locals {
raw_value = yamldecode(file("${path.module}/example.yaml"))
normalized_value = {
name = tostring(try(local.raw_value.name, null))
groups = try(local.raw_value.groups, [])
}
}
使用上述局部值表达式,模块中其他地方的配置可以引用 local.normalized_value
属性,而无需重复检查和处理否则会产生错误的缺失属性。
我们还可以使用 try
处理值可能以两种不同形式提供的情况,从而允许我们规范化为最通用的形式。
variable "example" {
type = any
}
locals {
example = try(
[tostring(var.example)],
tolist(var.example),
)
}
上述内容允许 var.example
为列表或单个字符串。如果它是一个字符串,则将其规范化为包含该字符串的单元素列表,同样允许配置中的其他表达式只假设 local.example
始终为列表。
第二个示例包含两个表达式,这两个表达式都可能失败。例如,如果 var.example
设置为 {}
,则它既不能转换为字符串也不能转换为列表。如果 try
用尽所有给定的表达式而没有成功,它将返回一个描述它遇到的所有问题的错误。
我们强烈建议仅在执行规范化的特殊局部值中使用 try
,以便错误处理仅限于模块中的单个位置,模块的其余部分可以只使用对规范化结构的简单引用,从而使未来的维护者更容易阅读。
try
函数只能捕获和处理运行时访问未知数据导致的动态错误。它不会捕获与可以证明对任何输入均无效的表达式相关的错误,例如格式错误的资源引用。
try
函数仅用于简洁地测试对象属性的存在性和类型。虽然它在技术上可以接受任何类型的表达式,但我们建议仅将其用于简单的属性引用和类型转换函数,如上例所示。过度使用try
来抑制错误会导致难以理解和维护的配置。
示例
> local.foo
{
"bar" = "baz"
}
> try(local.foo.bar, "fallback")
baz
> try(local.foo.boop, "fallback")
fallback
try
函数**不会**捕获与在动态表达式求值之前即可证明无效的结构相关的错误,例如格式错误的引用或对尚未声明的顶级对象的引用。
> try(local.nonexist, "fallback")
Error: Reference to undeclared local value
A local value with the name "nonexist" has not been declared.
相关函数
can
,它尝试评估表达式并返回一个布尔值,指示它是否成功。