@@ -442,8 +442,20 @@ type GQLExtensions struct {
442442//
443443// An empty value must be left out of the response, not sent as an empty object.
444444// Sending `"extensions":{}` would change the shape of every response.
445+ //
446+ // This asks the encoder rather than checking each field, so a field added later is
447+ // covered without editing here. Checking fields by hand means the next field added is
448+ // silently dropped from every response until someone remembers to update this.
449+ //
450+ // A value the encoder cannot handle is treated as empty. The warning is then missing,
451+ // which is better than failing the whole response over a diagnostic.
445452func (e * GQLExtensions ) IsEmpty () bool {
446- return e == nil || len (e .Warnings ) == 0
453+ if e == nil {
454+ return true
455+ }
456+
457+ data , err := json .Marshal (e )
458+ return err != nil || string (data ) == "{}"
447459}
448460
449461// GQLWarning describes something that happened during a request that worked. It is not
@@ -459,6 +471,13 @@ type GQLWarning struct {
459471 Message string `json:"message"`
460472
461473 // Detail holds values belonging to this warning. Optional.
474+ //
475+ // Everything here is sent to the caller and may also be logged, so do not put
476+ // secrets, credentials or identity material in it.
477+ //
478+ // Take care with counts and identifiers drawn from documents the caller is not
479+ // allowed to read. Saying how many documents were examined can tell the caller
480+ // about documents that access control hid from them.
462481 Detail map [string ]any `json:"detail,omitempty"`
463482}
464483
@@ -491,6 +510,11 @@ func (res *GQLResult) UnmarshalJSON(data []byte) error {
491510 }
492511 res .Data = out .Data
493512 res .Extensions = out .Extensions
513+ // A peer may send `"extensions":{}`, which decodes to a non nil empty value. Callers
514+ // are told the field is nil when there is nothing to report, so make that true.
515+ if res .Extensions .IsEmpty () {
516+ res .Extensions = nil
517+ }
494518 res .Errors = make ([]error , len (out .Errors ))
495519 for i , e := range out .Errors {
496520 res .Errors [i ] = ReviveError (e .Message )
0 commit comments