| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | package errors | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/goccy/go-yaml/printer" | 
					
						
							|  |  |  | 	"github.com/goccy/go-yaml/token" | 
					
						
							|  |  |  | 	"golang.org/x/xerrors" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-24 15:28:41 +09:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	defaultColorize      = false | 
					
						
							|  |  |  | 	defaultIncludeSource = true | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | var ( | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:26 +09:00
										 |  |  | 	ErrDecodeRequiredPointerType = xerrors.New("required pointer type value") | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:32:30 +09:00
										 |  |  | // Wrapf wrap error for stack trace | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func Wrapf(err error, msg string, args ...interface{}) error { | 
					
						
							|  |  |  | 	return &wrapError{ | 
					
						
							|  |  |  | 		baseError: &baseError{}, | 
					
						
							|  |  |  | 		err:       xerrors.Errorf(msg, args...), | 
					
						
							|  |  |  | 		nextErr:   err, | 
					
						
							|  |  |  | 		frame:     xerrors.Caller(1), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:32:30 +09:00
										 |  |  | // ErrSyntax create syntax error instance with message and token | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func ErrSyntax(msg string, tk *token.Token) *syntaxError { | 
					
						
							|  |  |  | 	return &syntaxError{ | 
					
						
							|  |  |  | 		baseError: &baseError{}, | 
					
						
							| 
									
										
										
										
											2019-10-23 16:08:21 +09:00
										 |  |  | 		msg:       msg, | 
					
						
							|  |  |  | 		token:     tk, | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 		frame:     xerrors.Caller(1), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type baseError struct { | 
					
						
							|  |  |  | 	state fmt.State | 
					
						
							|  |  |  | 	verb  rune | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (e *baseError) Error() string { | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (e *baseError) chainStateAndVerb(err error) { | 
					
						
							|  |  |  | 	wrapErr, ok := err.(*wrapError) | 
					
						
							|  |  |  | 	if ok { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 		wrapErr.state = e.state | 
					
						
							|  |  |  | 		wrapErr.verb = e.verb | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	syntaxErr, ok := err.(*syntaxError) | 
					
						
							|  |  |  | 	if ok { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 		syntaxErr.state = e.state | 
					
						
							|  |  |  | 		syntaxErr.verb = e.verb | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | type wrapError struct { | 
					
						
							|  |  |  | 	*baseError | 
					
						
							|  |  |  | 	err     error | 
					
						
							|  |  |  | 	nextErr error | 
					
						
							|  |  |  | 	frame   xerrors.Frame | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | type FormatErrorPrinter struct { | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	xerrors.Printer | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 	Colored    bool | 
					
						
							|  |  |  | 	InclSource bool | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-11 00:41:05 +09:00
										 |  |  | func (e *wrapError) As(target interface{}) bool { | 
					
						
							|  |  |  | 	err := e.nextErr | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		if wrapErr, ok := err.(*wrapError); ok { | 
					
						
							|  |  |  | 			err = wrapErr.nextErr | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return xerrors.As(err, target) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 23:59:27 +09:00
										 |  |  | func (e *wrapError) Unwrap() error { | 
					
						
							|  |  |  | 	return e.nextErr | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | func (e *wrapError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error { | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource}) | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (e *wrapError) FormatError(p xerrors.Printer) error { | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 	if _, ok := p.(*FormatErrorPrinter); !ok { | 
					
						
							|  |  |  | 		p = &FormatErrorPrinter{ | 
					
						
							| 
									
										
										
										
											2019-10-24 15:28:41 +09:00
										 |  |  | 			Printer:    p, | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 			Colored:    defaultColorize, | 
					
						
							|  |  |  | 			InclSource: defaultIncludeSource, | 
					
						
							| 
									
										
										
										
											2019-10-24 15:28:41 +09:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 	if e.verb == 'v' && e.state.Flag('+') { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 		// print stack trace for debugging | 
					
						
							|  |  |  | 		p.Print(e.err, "\n") | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 		e.frame.Format(p) | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 		e.chainStateAndVerb(e.nextErr) | 
					
						
							|  |  |  | 		return e.nextErr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err := e.nextErr | 
					
						
							|  |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 		if wrapErr, ok := err.(*wrapError); ok { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 			err = wrapErr.nextErr | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:26 +09:00
										 |  |  | 	e.chainStateAndVerb(err) | 
					
						
							|  |  |  | 	if fmtErr, ok := err.(xerrors.Formatter); ok { | 
					
						
							|  |  |  | 		fmtErr.FormatError(p) | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-10-23 16:40:26 +09:00
										 |  |  | 		p.Print(err) | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | type wrapState struct { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	org fmt.State | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (s *wrapState) Write(b []byte) (n int, err error) { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	return s.org.Write(b) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (s *wrapState) Width() (wid int, ok bool) { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	return s.org.Width() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (s *wrapState) Precision() (prec int, ok bool) { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	return s.org.Precision() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (s *wrapState) Flag(c int) bool { | 
					
						
							|  |  |  | 	// set true to 'printDetail' forced because when p.Detail() is false, xerrors.Printer no output any text | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	if c == '#' { | 
					
						
							|  |  |  | 		// ignore '#' keyword because xerrors.FormatError doesn't set true to printDetail. | 
					
						
							|  |  |  | 		// ( see https://github.com/golang/xerrors/blob/master/adaptor.go#L39-L43 ) | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 	return true | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (e *wrapError) Format(state fmt.State, verb rune) { | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	e.state = state | 
					
						
							|  |  |  | 	e.verb = verb | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 	xerrors.FormatError(e, &wrapState{org: state}, verb) | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (e *wrapError) Error() string { | 
					
						
							| 
									
										
										
										
											2019-10-24 15:28:41 +09:00
										 |  |  | 	var buf bytes.Buffer | 
					
						
							|  |  |  | 	e.PrettyPrint(&Sink{&buf}, defaultColorize, defaultIncludeSource) | 
					
						
							|  |  |  | 	return buf.String() | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | type syntaxError struct { | 
					
						
							|  |  |  | 	*baseError | 
					
						
							| 
									
										
										
										
											2019-10-23 16:08:21 +09:00
										 |  |  | 	msg   string | 
					
						
							|  |  |  | 	token *token.Token | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	frame xerrors.Frame | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | func (e *syntaxError) PrettyPrint(p xerrors.Printer, colored, inclSource bool) error { | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 	return e.FormatError(&FormatErrorPrinter{Printer: p, Colored: colored, InclSource: inclSource}) | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (e *syntaxError) FormatError(p xerrors.Printer) error { | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	var pp printer.Printer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var colored, inclSource bool | 
					
						
							| 
									
										
										
										
											2022-02-09 23:06:32 +00:00
										 |  |  | 	if fep, ok := p.(*FormatErrorPrinter); ok { | 
					
						
							|  |  |  | 		colored = fep.Colored | 
					
						
							|  |  |  | 		inclSource = fep.InclSource | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pos := fmt.Sprintf("[%d:%d] ", e.token.Position.Line, e.token.Position.Column) | 
					
						
							|  |  |  | 	msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, e.msg), colored) | 
					
						
							|  |  |  | 	if inclSource { | 
					
						
							|  |  |  | 		msg += "\n" + pp.PrintErrorToken(e.token, colored) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	p.Print(msg) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | 	if e.verb == 'v' && e.state.Flag('+') { | 
					
						
							|  |  |  | 		// %+v | 
					
						
							|  |  |  | 		// print stack trace for debugging | 
					
						
							|  |  |  | 		e.frame.Format(p) | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | type PrettyPrinter interface { | 
					
						
							|  |  |  | 	PrettyPrint(xerrors.Printer, bool, bool) error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type Sink struct{ *bytes.Buffer } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (es *Sink) Print(args ...interface{}) { | 
					
						
							|  |  |  | 	fmt.Fprint(es.Buffer, args...) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (es *Sink) Printf(f string, args ...interface{}) { | 
					
						
							|  |  |  | 	fmt.Fprintf(es.Buffer, f, args...) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (es *Sink) Detail() bool { | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 13:30:22 +09:00
										 |  |  | func (e *syntaxError) Error() string { | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	var buf bytes.Buffer | 
					
						
							| 
									
										
										
										
											2019-10-24 15:28:41 +09:00
										 |  |  | 	e.PrettyPrint(&Sink{&buf}, defaultColorize, defaultIncludeSource) | 
					
						
							| 
									
										
										
										
											2019-10-24 11:07:40 +09:00
										 |  |  | 	return buf.String() | 
					
						
							| 
									
										
										
										
											2019-10-23 03:21:42 +09:00
										 |  |  | } |