try
Syntax
try EXPRESSION
Returns
TryValue
The try
statement is a non-standard extension to Go’s text/template package. It introduces a mechanism for handling errors within templates, mimicking the try-catch
constructs found in other programming languages.
Methods
The TryValue
object encapsulates the result of evaluating the expression, and provides two methods:
- Err
- (
string
) Returns a string representation of the error thrown by the expression, if an error occurred, or returnsnil
if the expression evaluated without errors. - Value
- (
any
) Returns the result of the expression if the evaluation was successful, or returnsnil
if an error occurred while evaluating the expression.
Explanation
By way of example, let’s divide a number by zero:
{{ $x := 1 }}
{{ $y := 0 }}
{{ $result := div $x $y }}
{{ printf "%v divided by %v equals %v" $x $y .Value }}
As expected, the example above throws an error and fails the build:
Error: error calling div: can't divide the value by 0
Instead of failing the build, we can catch the error and emit a warning:
{{ $x := 1 }}
{{ $y := 0 }}
{{ with try (div $x $y) }}
{{ with .Err }}
{{ warnf "%s" . }}
{{ else }}
{{ printf "%v divided by %v equals %v" $x $y .Value }}
{{ end }}
{{ end }}
The error thrown by the expression is logged to the console as a warning:
WARN error calling div: can't divide the value by 0
Now let’s change the arguments to avoid dividing by zero:
{{ $x := 42 }}
{{ $y := 6 }}
{{ with try (div $x $y) }}
{{ with .Err }}
{{ warnf "%s" . }}
{{ else }}
{{ printf "%v divided by %v equals %v" $x $y .Value }}
{{ end }}
{{ end }}
Hugo renders the above to:
42 divided by 6 equals 7
Example
Error handling is essential when using the resources.GetRemote
function to capture remote resources such as data or images. When calling this function, if the HTTP request fails, Hugo will fail the build.
Instead of failing the build, we can catch the error and emit a warning:
{{ $url := "https://broken-example.org/images/a.jpg" }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ warnf "%s" . }}
{{ else with .Value }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ else }}
{{ warnf "Unable to get remote resource %q" $url }}
{{ end }}
{{ end }}
In the above, note that the context within the last conditional block is the TryValue
object returned by the try
statement. At this point neither the Err
nor Value
methods returned anything, so the current context is not useful. Use the $
to access the template context if needed.