go-yaml/internal/errors/error.go

176 lines
4.4 KiB
Go
Raw Normal View History

package errors
import (
"errors"
"fmt"
"reflect"
2024-11-14 16:01:08 +09:00
"github.com/goccy/go-yaml/ast"
"github.com/goccy/go-yaml/printer"
"github.com/goccy/go-yaml/token"
)
2024-11-14 16:01:08 +09:00
var (
As = errors.As
Is = errors.Is
New = errors.New
)
const (
2024-11-14 16:01:08 +09:00
defaultFormatColor = false
defaultIncludeSource = true
)
2024-11-14 16:01:08 +09:00
type PrettyFormatError interface {
FormatError(bool, bool) string
2019-10-23 13:30:22 +09:00
}
2024-11-14 16:01:08 +09:00
type SyntaxError struct {
Message string
Token *token.Token
}
2024-11-14 16:01:08 +09:00
type TypeError struct {
DstType reflect.Type
SrcType reflect.Type
StructFieldName *string
Token *token.Token
2019-10-23 13:30:22 +09:00
}
2024-11-14 16:01:08 +09:00
type OverflowError struct {
DstType reflect.Type
SrcNum string
Token *token.Token
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
type DuplicateKeyError struct {
Message string
Token *token.Token
}
2024-11-14 16:01:08 +09:00
type UnknownFieldError struct {
Message string
Token *token.Token
}
2024-11-14 16:01:08 +09:00
type UnexpectedNodeTypeError struct {
Actual ast.NodeType
Expected ast.NodeType
Token *token.Token
}
2024-11-14 16:01:08 +09:00
// ErrSyntax create syntax error instance with message and token
func ErrSyntax(msg string, tk *token.Token) *SyntaxError {
return &SyntaxError{
Message: msg,
Token: tk,
}
}
2024-11-14 16:01:08 +09:00
// ErrOverflow creates an overflow error instance with message and a token.
func ErrOverflow(dstType reflect.Type, num string, tk *token.Token) *OverflowError {
return &OverflowError{
DstType: dstType,
SrcNum: num,
Token: tk,
}
}
2024-11-14 16:01:08 +09:00
// ErrTypeMismatch cerates an type mismatch error instance with token.
func ErrTypeMismatch(dstType, srcType reflect.Type, token *token.Token) *TypeError {
return &TypeError{
DstType: dstType,
SrcType: srcType,
Token: token,
}
2024-11-14 16:01:08 +09:00
}
2024-11-14 16:01:08 +09:00
// ErrDuplicateKey creates an duplicate key error instance with token.
func ErrDuplicateKey(msg string, tk *token.Token) *DuplicateKeyError {
return &DuplicateKeyError{
Message: msg,
Token: tk,
}
2024-11-14 16:01:08 +09:00
}
2024-11-14 16:01:08 +09:00
// ErrUnknownField creates an unknown field error instance with token.
func ErrUnknownField(msg string, tk *token.Token) *UnknownFieldError {
return &UnknownFieldError{
Message: msg,
Token: tk,
}
}
2024-11-14 16:01:08 +09:00
func ErrUnexpectedNodeType(actual, expected ast.NodeType, tk *token.Token) *UnexpectedNodeTypeError {
return &UnexpectedNodeTypeError{
Actual: actual,
Expected: expected,
Token: tk,
}
}
2024-11-14 16:01:08 +09:00
func (e *SyntaxError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
func (e *SyntaxError) FormatError(colored, inclSource bool) string {
return formatError(e.Message, e.Token, colored, inclSource)
}
2019-10-24 11:07:40 +09:00
2024-11-14 16:01:08 +09:00
func (e *OverflowError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
}
2019-10-24 11:07:40 +09:00
2024-11-14 16:01:08 +09:00
func (e *OverflowError) FormatError(colored, inclSource bool) string {
return formatError(fmt.Sprintf("cannot unmarshal %s into Go value of type %s ( overflow )", e.SrcNum, e.DstType), e.Token, colored, inclSource)
}
2024-11-14 16:01:08 +09:00
func (e *TypeError) msg() string {
if e.StructFieldName != nil {
return fmt.Sprintf("cannot unmarshal %s into Go struct field %s of type %s", e.SrcType, *e.StructFieldName, e.DstType)
}
return fmt.Sprintf("cannot unmarshal %s into Go value of type %s", e.SrcType, e.DstType)
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
func (e *TypeError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
}
2019-10-24 11:07:40 +09:00
2024-11-14 16:01:08 +09:00
func (e *TypeError) FormatError(colored, inclSource bool) string {
return formatError(e.msg(), e.Token, colored, inclSource)
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
func (e *DuplicateKeyError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
func (e *DuplicateKeyError) FormatError(colored, inclSource bool) string {
return formatError(e.Message, e.Token, colored, inclSource)
2019-10-24 11:07:40 +09:00
}
2024-11-14 16:01:08 +09:00
func (e *UnknownFieldError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
}
2024-11-14 16:01:08 +09:00
func (e *UnknownFieldError) FormatError(colored, inclSource bool) string {
return formatError(e.Message, e.Token, colored, inclSource)
}
2024-11-14 16:01:08 +09:00
func (e *UnexpectedNodeTypeError) Error() string {
return e.FormatError(defaultFormatColor, defaultIncludeSource)
}
2024-11-14 16:01:08 +09:00
func (e *UnexpectedNodeTypeError) FormatError(colored, inclSource bool) string {
return formatError(fmt.Sprintf("%s was used where %s is expected", e.Actual.YAMLName(), e.Expected.YAMLName()), e.Token, colored, inclSource)
}
2024-11-14 16:01:08 +09:00
func formatError(errMsg string, token *token.Token, colored, inclSource bool) string {
var pp printer.Printer
2024-11-14 16:01:08 +09:00
pos := fmt.Sprintf("[%d:%d] ", token.Position.Line, token.Position.Column)
msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, errMsg), colored)
if inclSource {
2024-11-14 16:01:08 +09:00
msg += "\n" + pp.PrintErrorToken(token, colored)
}
2024-11-14 16:01:08 +09:00
return msg
}