go: text/template: wrap errors returned by custom template functions

What version of Go are you using (go version)?

go version go1.13 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\User\AppData\Local\go-build
set GOENV=C:\Users\User\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=D:\Go
set GOPRIVATE=
set GOPROXY=direct
set GOROOT=C:\Go\go1.13
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Go\go1.13\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=E:\Projects\test\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\User\AppData\Local\Temp\go-build112356450=/tmp/go-build -gno-record-gcc-switches

What did you do?

I’m trying to get the error returned by my custom template function. The error is a struct implementing the error interface.

Execute returns template.ExecError and despite the fact that it implements Unwrap() error, calling Unwrap returns *errors.errorsString, not my error implementation.

Thus, there is no way to get the original error.

Code:

package main

import (
	"errors"
	"fmt"
	"os"
	"text/template"
)

type MyError struct {
	Value int
}

func (e *MyError) Error() string { return "error message" }

func test(val int) (string, error) {
	return "", &MyError{
		Value: val,
	}
}

func main() {
	t := template.Must(template.New("test").Funcs(template.FuncMap{
		"test": test,
	}).Parse("{{ test 10 }}"))

	err := t.Execute(os.Stdout, nil)

	if err != nil {
		var e *MyError
		fmt.Println(errors.As(err, &e)) // <-- false
	}
}

What did you expect to see?

true

What did you see instead?

false

Additional notes

  1. Documentation for template.FuncMap states that:

if the second (error) return value evaluates to non-nil during execution, execution terminates and Execute returns that error

  1. The same applies for method calls like {{ .Object.Method }}.

  2. Both text/template and html/template are affected.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 4
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I’ll add some tests right away so that it’s ready for 1.17

Maybe you’re right, I’m not sure. My instinct is that this kind of internal change, even if it’s definitely correct, could very easily change the behavior of existing programs. So my default response is that three weeks before the final release is too late, given that there’s nearly no time to get it tested.

Then again, rc1 is late so that could still work as a way to get it tested. Normally it would already be out by now.

In any case, let me know how I can help make progress getting this fixed.

Sending a new CL to advance the change sounds like the right way. At minimum, the original change needs a test, like Ian said.