mirror of
https://github.com/golang/go
synced 2024-11-07 20:06:21 -07:00
text/template: wrap errors returned by template functions instead of stringifying them
Fixes #34201
Change-Id: Ic2e2967e4b01167345cf38bd006cabb206a64377
GitHub-Last-Rev: 5d0c485655
GitHub-Pull-Request: golang/go#42398
Reviewed-on: https://go-review.googlesource.com/c/go/+/267838
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Trust: Daniel Martí <mvdan@mvdan.cc>
Trust: Pontus Leitzler <leitzler@gmail.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
67b9ecb23b
commit
d4247f5167
@ -727,7 +727,7 @@ func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, a
|
|||||||
// error to the caller.
|
// error to the caller.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.at(node)
|
s.at(node)
|
||||||
s.errorf("error calling %s: %v", name, err)
|
s.errorf("error calling %s: %w", name, err)
|
||||||
}
|
}
|
||||||
if v.Type() == reflectValueType {
|
if v.Type() == reflectValueType {
|
||||||
v = v.Interface().(reflect.Value)
|
v = v.Interface().(reflect.Value)
|
||||||
|
@ -902,6 +902,28 @@ func TestExecError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CustomError struct{}
|
||||||
|
|
||||||
|
func (*CustomError) Error() string { return "heyo !" }
|
||||||
|
|
||||||
|
// Check that a custom error can be returned.
|
||||||
|
func TestExecError_CustomError(t *testing.T) {
|
||||||
|
failingFunc := func() (string, error) {
|
||||||
|
return "", &CustomError{}
|
||||||
|
}
|
||||||
|
tmpl := Must(New("top").Funcs(FuncMap{
|
||||||
|
"err": failingFunc,
|
||||||
|
}).Parse("{{ err }}"))
|
||||||
|
|
||||||
|
var b bytes.Buffer
|
||||||
|
err := tmpl.Execute(&b, nil)
|
||||||
|
|
||||||
|
var e *CustomError
|
||||||
|
if !errors.As(err, &e) {
|
||||||
|
t.Fatalf("expected custom error; got %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestJSEscaping(t *testing.T) {
|
func TestJSEscaping(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
in, exp string
|
in, exp string
|
||||||
|
@ -23,6 +23,9 @@ import (
|
|||||||
// return value evaluates to non-nil during execution, execution terminates and
|
// return value evaluates to non-nil during execution, execution terminates and
|
||||||
// Execute returns that error.
|
// Execute returns that error.
|
||||||
//
|
//
|
||||||
|
// Errors returned by Execute wrap the underlying error; call errors.As to
|
||||||
|
// uncover them.
|
||||||
|
//
|
||||||
// When template execution invokes a function with an argument list, that list
|
// When template execution invokes a function with an argument list, that list
|
||||||
// must be assignable to the function's parameter types. Functions meant to
|
// must be assignable to the function's parameter types. Functions meant to
|
||||||
// apply to arguments of arbitrary type can use parameters of type interface{} or
|
// apply to arguments of arbitrary type can use parameters of type interface{} or
|
||||||
@ -344,7 +347,7 @@ func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) {
|
|||||||
|
|
||||||
var err error
|
var err error
|
||||||
if argv[i], err = prepareArg(arg, argType); err != nil {
|
if argv[i], err = prepareArg(arg, argType); err != nil {
|
||||||
return reflect.Value{}, fmt.Errorf("arg %d: %s", i, err)
|
return reflect.Value{}, fmt.Errorf("arg %d: %w", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return safeCall(fn, argv)
|
return safeCall(fn, argv)
|
||||||
|
Loading…
Reference in New Issue
Block a user