Closed GreatDanton closed 11 months ago
It would be helpful if you can provide a full example (either as a program or test) that I can copy/paste to demonstrate/reproduce the problem. In your example there's lots of missing references and such.
I hope this is better
package main
import (
"errors"
"fmt"
"github.com/BurntSushi/toml"
"log"
"strings"
)
type CustomType uint8
func (n *CustomType) UnmarshalText(text []byte) error {
t := strings.TrimSpace(string(text))
switch t {
case "number_and_text":
*n = 0
case "number":
*n = 1
case "text":
*n = 2
default:
// TODO: how can I get a line number or the name of a currently decoded field here?
// I am trying to decode multiple fields of this same type (CustomType), so I
// need some way to distinguish between them.
return fmt.Errorf("invalid reference type: available options [%d, %d, %d], but got: %q", 0, 1, 2, t)
}
return nil
}
type MyConfig struct {
Field1 CustomType `toml:"field1"`
Field2 CustomType `toml:"field2"`
Field3 CustomType `toml:"field3"`
}
func main() {
CONFIG := `
field1 = "number_and_text"
field2 = "number"
field3 = "invalid enum"
`
config := &MyConfig{}
md, err := toml.Decode(CONFIG, config)
if err != nil {
var pErr toml.ParseError
if errors.As(err, &pErr) {
log.Fatalf("toml: config parse error: %v", pErr.ErrorWithUsage())
}
// err could not be cast to a toml.ParseError, which means our own unmarshaller
// returned an error. Here I would need some way to report which field has invalid
// value (field1, field2 or field3?)
if false {
// md contains context with our field that reported a decode error, but
// it's a private member
fmt.Println(md)
}
log.Fatalf("toml: config parse error: %v", err)
}
}
Cheers; that's helpful. I'll have a look tomorrow.
Sorry, I forgot about your issue.
I fixed it; if you use go get github.com/BurntSushi/toml@master
you should automatically get a ParseError, and your code should work.
When decoding built in types, I found out that toml.Decode() method returns a ParseError which contains lots of context about the error. When unmarshalling custom structs, however, I don't know how am I supposed to obtain such context (I would like to know at least the name of the field or the line number of the user text).
More context about my problem: In my case I have a custom type which tries to parse user value and return an error on invalid enum: