diff options
author | Luke Shumaker <lukeshu@datawire.io> | 2022-08-14 20:52:06 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@datawire.io> | 2022-08-16 00:05:24 -0600 |
commit | 54bbd1e59317a6e9658eb8098657078cc8e81979 (patch) | |
tree | 0d7033a0644945dedfe0fca158e0c40864f759f6 /errors.go | |
parent | 2ae2ebe2a5ac712db6f9221cb1ad8cfa76aad180 (diff) |
wip: Reduce test differences [ci-skip]
- Handle UTF-16 surrogate pairs
- Handle cycles in values
- Handle cycles in types
- Better errors
- Handle case-folding of struct field names
- Allow []byteTypeWithMethods
- Fix struct field-order
- Fix handling of interfaces storing pointers
- Enforce a maximum decode depth
- Validate struct tags
Diffstat (limited to 'errors.go')
-rw-r--r-- | errors.go | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..a5a4080 --- /dev/null +++ b/errors.go @@ -0,0 +1,130 @@ +// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package lowmemjson + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "errors" +) + +// low-level decode errors ///////////////////////////////////////////////////////////////////////// +// These will be wrapped in a *DecodeError. + +// A *DecodeReadError is returned from Decode if there is an I/O error +// reading the input. +type DecodeReadError struct { + Err error + Offset int64 +} + +func (e *DecodeReadError) Error() string { + return fmt.Sprintf("json: I/O error at input byte %v: %v", e.Offset, e.Err) +} +func (e *DecodeReadError) Unwrap() error { return e.Err } + +// A *DecodeSyntaxError is returned from Decode if there is a syntax +// error in the input. +type DecodeSyntaxError struct { + Err error + Offset int64 +} + +func (e *DecodeSyntaxError) Error() string { + return fmt.Sprintf("json: syntax error at input byte %v: %v", e.Offset, e.Err) +} + +// A *DecodeTypeError is returned from Decode if the JSON input is not +// appropriate for the given Go type. +// +// If a .DecodeJSON, .UnmarshalJSON, or .UnmashaleText method returns +// an error, it is wrapped in a *DecodeTypeError. +type DecodeTypeError struct { + JSONType string // (optional) + GoType reflect.Type + Offset int64 + Err error // (optional) +} + +func (e *DecodeTypeError) Error() string { + var buf strings.Builder + buf.WriteString("json: cannot decode ") + if e.JSONType != "" { + fmt.Fprintf(&buf, "JSON %s ", e.JSONType) + } + fmt.Fprintf(&buf, "at input byte %v in to Go %v", e.Offset, e.GoType) + if e.Err != nil { + fmt.Fprintf(&buf, ": %v", strings.TrimPrefix(e.Err.Error(), "json: ")) + } + return buf.String() +} + +func (e *DecodeTypeError) Unwrap() error { return e.Err } + +var ErrDecodeExceededMaxDepth = errors.New("exceeded max depth") + +// high-level decode errors //////////////////////////////////////////////////////////////////////// + +// A *DecodeArgumentError is returned from Decode if the argument is +// not a non-nil pointer or is not settable. +// +// Alternatively, a *DecodeArgument error may be found inside of a +// *DecodeTypeError if the type being decoded in to is not a type that +// can be decoded in to (such as map with non-stringable type as +// keys). +// +// type DecodeArgumentError struct { +// Type reflect.Type +// } +type DecodeArgumentError = json.InvalidUnmarshalError + +type DecodeError struct { + Field string + Err error + + FieldParent string // for compat + FieldName string // for compat +} + +func (e *DecodeError) Error() string { + return fmt.Sprintf("json: %s: %s", e.Field, strings.TrimPrefix(e.Err.Error(), "json: ")) +} +func (e *DecodeError) Unwrap() error { return e.Err } + +// encode errors /////////////////////////////////////////////////////////////////////////////////// + +// An *EncodeTypeError is returned by Encode when attempting to encode +// an unsupported type. +// +// type EncodeTypeError struct { +// Type reflect.Type +// } +type EncodeTypeError = json.UnsupportedTypeError + +// An *EncodeValueError is returned by Encode when attempting to +// encode an unsupported value (such as a datastructure with a cycle). +// +// type UnsupportedValueError struct { +// Value reflect.Value +// Str string +// } +type EncodeValueError = json.UnsupportedValueError + +// An *EncodeTypeError is returned by Encode when attempting to encode +// an unsupported value type. +type EncodeMethodError struct { + Type reflect.Type + Err error + SourceFunc string +} + +func (e *EncodeMethodError) Error() string { + return fmt.Sprintf("json: error calling %v for type %v: %v", + e.SourceFunc, e.Type, strings.TrimPrefix(e.Err.Error(), "json: ")) +} + +func (e *EncodeMethodError) Unwrap() error { return e.Err } |