diff options
| author | Joe Tsai <joetsai@digital-static.net> | 2025-09-08 17:33:47 -0700 |
|---|---|---|
| committer | Joseph Tsai <joetsai@digital-static.net> | 2025-09-10 00:58:35 -0700 |
| commit | 30686c4cc89e6952ec00846e34016f37d53f31dd (patch) | |
| tree | 3a9648a9c491c5e12d9b6df0f24815d0256bc429 /src/encoding/json | |
| parent | c5737dc21bbac9fbefc35ac9313e66291d66b382 (diff) | |
| download | go-30686c4cc89e6952ec00846e34016f37d53f31dd.tar.xz | |
encoding/json/v2: document context annotation with SemanticError
When the json package calls
Marshaler, MarshalerTo, Unmarshaler, or UnmarshalerFrom methods
and a SemanticError is returned, it will automatically
annotate the error with context.
Document this behavior.
Change-Id: Id8e775a7c1c2a6ffc29ea518913591915e8aff87
Reviewed-on: https://go-review.googlesource.com/c/go/+/701956
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/encoding/json')
| -rw-r--r-- | src/encoding/json/v2/arshal_methods.go | 18 | ||||
| -rw-r--r-- | src/encoding/json/v2/errors.go | 5 | ||||
| -rw-r--r-- | src/encoding/json/v2/example_orderedobject_test.go | 4 |
3 files changed, 26 insertions, 1 deletions
diff --git a/src/encoding/json/v2/arshal_methods.go b/src/encoding/json/v2/arshal_methods.go index 664c3927cc..2decd144db 100644 --- a/src/encoding/json/v2/arshal_methods.go +++ b/src/encoding/json/v2/arshal_methods.go @@ -41,6 +41,10 @@ var ( // // It is recommended that implementations return a buffer that is safe // for the caller to retain and potentially mutate. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. type Marshaler interface { MarshalJSON() ([]byte, error) } @@ -54,6 +58,11 @@ type Marshaler interface { // // The implementation must write only one JSON value to the Encoder and // must not retain the pointer to [jsontext.Encoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// unless it is an IO error. type MarshalerTo interface { MarshalJSONTo(*jsontext.Encoder) error @@ -72,6 +81,10 @@ type MarshalerTo interface { // unmarshaling into a pre-populated value. // // Implementations must not retain or mutate the input []byte. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. type Unmarshaler interface { UnmarshalJSON([]byte) error } @@ -88,6 +101,11 @@ type Unmarshaler interface { // unmarshaling into a pre-populated value. // // Implementations must not retain the pointer to [jsontext.Decoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// unless it is a [jsontext.SyntacticError] or an IO error. type UnmarshalerFrom interface { UnmarshalJSONFrom(*jsontext.Decoder) error diff --git a/src/encoding/json/v2/errors.go b/src/encoding/json/v2/errors.go index 940b720210..9485d7b527 100644 --- a/src/encoding/json/v2/errors.go +++ b/src/encoding/json/v2/errors.go @@ -62,6 +62,11 @@ func isFatalError(err error, flags jsonflags.Flags) bool { // SemanticError describes an error determining the meaning // of JSON data as Go data or vice-versa. // +// If a [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom] method +// returns a SemanticError when called by the [json] package, +// then the ByteOffset, JSONPointer, and GoType fields are automatically +// populated by the calling context if they are the zero value. +// // The contents of this error as produced by this package may change over time. type SemanticError struct { requireKeyedLiterals diff --git a/src/encoding/json/v2/example_orderedobject_test.go b/src/encoding/json/v2/example_orderedobject_test.go index d68782f725..fc23132504 100644 --- a/src/encoding/json/v2/example_orderedobject_test.go +++ b/src/encoding/json/v2/example_orderedobject_test.go @@ -53,7 +53,9 @@ func (obj *OrderedObject[V]) MarshalJSONTo(enc *jsontext.Encoder) error { // UnmarshalJSONFrom decodes a JSON object from dec into obj. func (obj *OrderedObject[V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { if k := dec.PeekKind(); k != '{' { - return fmt.Errorf("expected object start, but encountered %v", k) + // The [json] package automatically populates relevant fields + // in a [json.SemanticError] to provide additional context. + return &json.SemanticError{JSONKind: k} } if _, err := dec.ReadToken(); err != nil { return err |
