Skip to content

Commit 30686c4

Browse files
committed
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 <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent c5737dc commit 30686c4

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

src/encoding/json/v2/arshal_methods.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ var (
4141
//
4242
// It is recommended that implementations return a buffer that is safe
4343
// for the caller to retain and potentially mutate.
44+
//
45+
// If the returned error is a [SemanticError], then unpopulated fields
46+
// of the error may be populated by [json] with additional context.
47+
// Errors of other types are wrapped within a [SemanticError].
4448
type Marshaler interface {
4549
MarshalJSON() ([]byte, error)
4650
}
@@ -54,6 +58,11 @@ type Marshaler interface {
5458
//
5559
// The implementation must write only one JSON value to the Encoder and
5660
// must not retain the pointer to [jsontext.Encoder].
61+
//
62+
// If the returned error is a [SemanticError], then unpopulated fields
63+
// of the error may be populated by [json] with additional context.
64+
// Errors of other types are wrapped within a [SemanticError],
65+
// unless it is an IO error.
5766
type MarshalerTo interface {
5867
MarshalJSONTo(*jsontext.Encoder) error
5968

@@ -72,6 +81,10 @@ type MarshalerTo interface {
7281
// unmarshaling into a pre-populated value.
7382
//
7483
// Implementations must not retain or mutate the input []byte.
84+
//
85+
// If the returned error is a [SemanticError], then unpopulated fields
86+
// of the error may be populated by [json] with additional context.
87+
// Errors of other types are wrapped within a [SemanticError].
7588
type Unmarshaler interface {
7689
UnmarshalJSON([]byte) error
7790
}
@@ -88,6 +101,11 @@ type Unmarshaler interface {
88101
// unmarshaling into a pre-populated value.
89102
//
90103
// Implementations must not retain the pointer to [jsontext.Decoder].
104+
//
105+
// If the returned error is a [SemanticError], then unpopulated fields
106+
// of the error may be populated by [json] with additional context.
107+
// Errors of other types are wrapped within a [SemanticError],
108+
// unless it is a [jsontext.SyntacticError] or an IO error.
91109
type UnmarshalerFrom interface {
92110
UnmarshalJSONFrom(*jsontext.Decoder) error
93111

src/encoding/json/v2/errors.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ func isFatalError(err error, flags jsonflags.Flags) bool {
6262
// SemanticError describes an error determining the meaning
6363
// of JSON data as Go data or vice-versa.
6464
//
65+
// If a [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom] method
66+
// returns a SemanticError when called by the [json] package,
67+
// then the ByteOffset, JSONPointer, and GoType fields are automatically
68+
// populated by the calling context if they are the zero value.
69+
//
6570
// The contents of this error as produced by this package may change over time.
6671
type SemanticError struct {
6772
requireKeyedLiterals

src/encoding/json/v2/example_orderedobject_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ func (obj *OrderedObject[V]) MarshalJSONTo(enc *jsontext.Encoder) error {
5353
// UnmarshalJSONFrom decodes a JSON object from dec into obj.
5454
func (obj *OrderedObject[V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
5555
if k := dec.PeekKind(); k != '{' {
56-
return fmt.Errorf("expected object start, but encountered %v", k)
56+
// The [json] package automatically populates relevant fields
57+
// in a [json.SemanticError] to provide additional context.
58+
return &json.SemanticError{JSONKind: k}
5759
}
5860
if _, err := dec.ReadToken(); err != nil {
5961
return err

0 commit comments

Comments
 (0)