hugo: Add a way for the user to control errors in resources.Get

See https://discourse.gohugo.io/t/0-90-0-how-to-check-for-local-resource-existence/35954

In getJSON we have a rather intricate setup where we allow users to “ignore” HTTP errors.

I’m not a big fan of this construct, but we probably need a better way to allow the users handle this themselves.

We have talked about this before, but since then we have better control of the truth function in Go templates, so it should be able to do something ala:

{{ $image := with resources.Get "https://example.org/image.jpg }}
{{ with $image }}
{{ else }}
{{ with $image.Error }}
// Ignore or log
{{ end 
{{ end }}

I’m not totally sure if the above is a great idea or not …

/cc @jmooring @regisphilibert etc.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 25 (24 by maintainers)

Commits related to this issue

Most upvoted comments

Should users not only run into these types of issues during changes/development?

What if a remote server is down when building your site on some CI server?

The thing is, this is very contextual. I would say that in most situations, the current behaviour of “stop the build as fast as possible” is the best thing to do. But there are exceptions – and if you have a fragile remote service somewhere it may make sense to just drop that content or display some default content…

The thing is, I would possibly consider a breaking change like this if it was cleaner/easier/simpler/better (and preferably much) to implement:

Compare these two:

{{ $result := resources.Get "https://gohugo.io/img/hugo-logo.png" }}
{{ with $result }}
        <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ else  }}
        {{ $result.Err }} // If $result is not a resource it's an error 
{{ end }}
{{ $result := resources.Get "https://gohugo.io/img/hugo-logo.png" }}
{{ with $result }}
        {{ if .Err }}
        {{ else }}
        <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
        {{ end }}
{{ end }}

The latter example is fully backwards compatible**, it’s a pattern that is fairly simple to implement (no trickery with the truth function used in with) and it’s fairly easy understand and expand to the other APIs we have, if needed.

** Breakages in the first example: All errors must be handled by the user, $result cannot be compared to nil.

@bep Would your suggestion apply to all methods for both global and page resources? Thinking of:

I like your suggestion. To fail quietly:

{{ with resources.Get "https://gohugo.io/img/hugo-logo.png" }}
  {{ if not .Error }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
  {{ end }}
{{ end }}

@regisphilibert hmm… that’s probably more added complexity than I’m prepared to take on.

I have thought a little, and suggest:

{{ $image := with resources.Get "https://example.org/image.jpg }}
{{ with $image }}
// This means we either have a valid image or an Error (any remote 404 means a nil value, aka not found)
// If you do this and there is an error situation, you will get an ERROR in the log (this is more or less how it behaves today)
{{ .RelPermalink }}
// To handle that error you would do something ALA:
{{ if .Error }}
{{ else }}
{{ .RelPermalink }}
{{ end }}
{{ end }}

I think being able to interpret the error is always great and that’s been lacking in getJSON etc… So I would, for one, love to be able to read the error when it happens, and decide what to do.

I’m not sure I trust $image value to test the success of my “fetch”. It could very well return an empty array. I wonder if we couldn’t add a OK or .Success in there so the user can choose to trust the falsy/truthy value of $image or rely on a more trustworthy $image.OK. This might not be very useful here, but if this was added to getJSON it would have value I believe.

{{ $image := with resources.Get "https://example.org/image.jpg }}
{{ with $image.OK }}
  // deal with $image's value even if empty array
{{ else }}
  {{ with $image.Error }}
  // Ignore or log
  {{ end 
{{ end }}