git.lukeshu.com/go/lowmemjson@v0.3.9-0.20230723050957-72f6d13f6fb2/errors.go (about) 1 // Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> 2 // 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 package lowmemjson 6 7 import ( 8 "encoding/json" 9 "errors" 10 "fmt" 11 "reflect" 12 "strings" 13 14 "git.lukeshu.com/go/lowmemjson/internal/jsonparse" 15 ) 16 17 // ErrInvalidUnreadRune is returned to Decodable.DecodeJSON(scanner) 18 // implementations from scanner.UnreadRune() if the last operation was 19 // not a successful .ReadRune() call. 20 var ErrInvalidUnreadRune = errors.New("lowmemjson: invalid use of UnreadRune") 21 22 // parser errors /////////////////////////////////////////////////////////////////////////////////// 23 24 // ErrParserExceededMaxDepth is the base error that a 25 // *DecodeSyntaxError wraps when the depth of the JSON document 26 // exceeds 10000. 27 var ErrParserExceededMaxDepth = jsonparse.ErrParserExceededMaxDepth 28 29 // low-level decode errors ///////////////////////////////////////////////////////////////////////// 30 // These will be wrapped in a *DecodeError. 31 32 // A DecodeReadError is returned from Decode (wrapped in a 33 // *DecodeError) if there is an I/O error reading the input. 34 type DecodeReadError struct { 35 Err error 36 Offset int64 37 } 38 39 func (e *DecodeReadError) Error() string { 40 return fmt.Sprintf("json: I/O error at input byte %v: %v", e.Offset, e.Err) 41 } 42 func (e *DecodeReadError) Unwrap() error { return e.Err } 43 44 // A DecodeSyntaxError is returned from Decode (wrapped in a 45 // *DecodeError) if there is a syntax error in the input. 46 type DecodeSyntaxError struct { 47 Err error 48 Offset int64 49 } 50 51 func (e *DecodeSyntaxError) Error() string { 52 return fmt.Sprintf("json: syntax error at input byte %v: %v", e.Offset, e.Err) 53 } 54 func (e *DecodeSyntaxError) Unwrap() error { return e.Err } 55 56 // A DecodeTypeError is returned from Decode (wrapped in a 57 // *DecodeError) if the JSON input is not appropriate for the given Go 58 // type. 59 // 60 // If a .DecodeJSON, .UnmarshalJSON, or .UnmashaleText method returns 61 // an error, it is wrapped in a *DecodeTypeError. 62 type DecodeTypeError struct { 63 JSONType string // (optional) 64 GoType reflect.Type 65 Offset int64 66 Err error // (optional) 67 } 68 69 func (e *DecodeTypeError) Error() string { 70 var buf strings.Builder 71 buf.WriteString("json: cannot decode ") 72 if e.JSONType != "" { 73 fmt.Fprintf(&buf, "JSON %s ", e.JSONType) 74 } 75 fmt.Fprintf(&buf, "at input byte %v into Go %v", e.Offset, e.GoType) 76 if e.Err != nil { 77 fmt.Fprintf(&buf, ": %v", strings.TrimPrefix(e.Err.Error(), "json: ")) 78 } 79 return buf.String() 80 } 81 82 func (e *DecodeTypeError) Unwrap() error { return e.Err } 83 84 // ErrDecodeNonEmptyInterface is the base error that a 85 // *DecodeTypeError wraps when Decode is asked to unmarshal into an 86 // `interface` type that has one or more methods. 87 var ErrDecodeNonEmptyInterface = errors.New("cannot decode into non-empty interface") 88 89 // high-level decode errors //////////////////////////////////////////////////////////////////////// 90 91 // A DecodeArgumentError is returned from Decode if the argument is 92 // not a non-nil pointer or is not settable. 93 // 94 // Alternatively, a *DecodeArgument error may be found inside of a 95 // *DecodeTypeError if the type being decoded into is not a type that 96 // can be decoded into (such as map with non-stringable type as keys). 97 // 98 // type DecodeArgumentError struct { 99 // Type reflect.Type 100 // } 101 type DecodeArgumentError = json.InvalidUnmarshalError 102 103 // A DecodeError is returned from Decode for all errors except for 104 // *DecodeArgumentError. 105 // 106 // A *DecodeError wraps *DecodeSyntaxError for malformed or illegal 107 // input, *DecodeTypeError for Go type issues, or *DecodeReadError for 108 // I/O errors. 109 type DecodeError struct { 110 Field string // Where in the JSON the error was, in the form "v[idx][idx][idx]". 111 Err error // What the error was. 112 113 FieldParent string // for compat; the same as encoding/json.UnmarshalTypeError.Struct 114 FieldName string // for compat; the same as encoding/json.UnmarshalTypeError.Field 115 } 116 117 func (e *DecodeError) Error() string { 118 return fmt.Sprintf("json: %s: %s", e.Field, strings.TrimPrefix(e.Err.Error(), "json: ")) 119 } 120 func (e *DecodeError) Unwrap() error { return e.Err } 121 122 // encode errors /////////////////////////////////////////////////////////////////////////////////// 123 124 // A EncodeWriteError is returned from Encode if there is an error 125 // writing to the output stream. 126 type EncodeWriteError struct { 127 Err error 128 Offset int64 129 } 130 131 func (e *EncodeWriteError) Error() string { 132 return fmt.Sprintf("json: I/O error at output byte %v: %v", e.Offset, e.Err) 133 } 134 func (e *EncodeWriteError) Unwrap() error { return e.Err } 135 136 // An EncodeTypeError is returned by Encode when attempting to encode 137 // an unsupported type. 138 // 139 // type EncodeTypeError struct { 140 // Type reflect.Type 141 // } 142 type EncodeTypeError = json.UnsupportedTypeError 143 144 // An EncodeValueError is returned by Encode when attempting to encode 145 // an unsupported value (such as a datastructure with a cycle, or (if 146 // InvalidUTF8=InvalidUTF8Error) a string with invalid UTF-8). 147 // 148 // type UnsupportedValueError struct { 149 // Value reflect.Value 150 // Str string 151 // } 152 type EncodeValueError = json.UnsupportedValueError 153 154 // An EncodeMethodError either wraps an error that is returned from an 155 // object's method when encoding that object to JSON, or wraps a 156 // *ReEncodeSyntaxError for the method's output. 157 type EncodeMethodError struct { 158 Type reflect.Type // The Go type that the method is on 159 SourceFunc string // The method: "EncodeJSON", "MarshalJSON", or "MarshalText" 160 Err error // The error that the method returned 161 } 162 163 func (e *EncodeMethodError) Error() string { 164 return fmt.Sprintf("json: error calling %v for type %v: %v", 165 e.SourceFunc, e.Type, strings.TrimPrefix(e.Err.Error(), "json: ")) 166 } 167 func (e *EncodeMethodError) Unwrap() error { return e.Err } 168 169 // reencode errors ///////////////////////////////////////////////////////////////////////////////// 170 171 // A ReEncodeWriteError is returned from ReEncoder's methods if there 172 // is an error writing to the output stream. 173 type ReEncodeWriteError struct { 174 Err error 175 Offset int64 176 } 177 178 func (e *ReEncodeWriteError) Error() string { 179 return fmt.Sprintf("json: I/O error at output byte %v: %v", e.Offset, e.Err) 180 } 181 func (e *ReEncodeWriteError) Unwrap() error { return e.Err } 182 183 // A ReEncodeSyntaxError is returned from ReEncoder's methods if there 184 // is a syntax error in the input. 185 type ReEncodeSyntaxError struct { 186 Err error 187 Offset int64 188 } 189 190 func (e *ReEncodeSyntaxError) Error() string { 191 return fmt.Sprintf("json: syntax error at input byte %v: %v", e.Offset, e.Err) 192 } 193 func (e *ReEncodeSyntaxError) Unwrap() error { return e.Err }