...

Source file src/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go

Documentation: github.com/99designs/gqlgen/graphql/handler/transport

     1  package transport
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/vektah/gqlparser/v2/gqlerror"
     7  )
     8  
     9  // A private key for context that only this package can access. This is important
    10  // to prevent collisions between different context uses
    11  var wsSubscriptionErrorCtxKey = &wsSubscriptionErrorContextKey{"subscription-error"}
    12  
    13  type wsSubscriptionErrorContextKey struct {
    14  	name string
    15  }
    16  
    17  type subscriptionError struct {
    18  	errs []*gqlerror.Error
    19  }
    20  
    21  // AddSubscriptionError is used to let websocket return an error message after subscription resolver returns a channel.
    22  // for example:
    23  //
    24  //	func (r *subscriptionResolver) Method(ctx context.Context) (<-chan *model.Message, error) {
    25  //		ch := make(chan *model.Message)
    26  //		go func() {
    27  //	     defer func() {
    28  //				close(ch)
    29  //	     }
    30  //			// some kind of block processing (e.g.: gRPC client streaming)
    31  //			stream, err := gRPCClientStreamRequest(ctx)
    32  //			if err != nil {
    33  //				   transport.AddSubscriptionError(ctx, err)
    34  //	            return // must return and close channel so websocket can send error back
    35  //	     }
    36  //			for {
    37  //				m, err := stream.Recv()
    38  //				if err == io.EOF {
    39  //					return
    40  //				}
    41  //				if err != nil {
    42  //				   transport.AddSubscriptionError(ctx, err)
    43  //	            return // must return and close channel so websocket can send error back
    44  //				}
    45  //				ch <- m
    46  //			}
    47  //		}()
    48  //
    49  //		return ch, nil
    50  //	}
    51  //
    52  // see https://github.com/99designs/gqlgen/pull/2506 for more details
    53  func AddSubscriptionError(ctx context.Context, err *gqlerror.Error) {
    54  	subscriptionErrStruct := getSubscriptionErrorStruct(ctx)
    55  	subscriptionErrStruct.errs = append(subscriptionErrStruct.errs, err)
    56  }
    57  
    58  func withSubscriptionErrorContext(ctx context.Context) context.Context {
    59  	return context.WithValue(ctx, wsSubscriptionErrorCtxKey, &subscriptionError{})
    60  }
    61  
    62  func getSubscriptionErrorStruct(ctx context.Context) *subscriptionError {
    63  	v, _ := ctx.Value(wsSubscriptionErrorCtxKey).(*subscriptionError)
    64  	return v
    65  }
    66  
    67  func getSubscriptionError(ctx context.Context) []*gqlerror.Error {
    68  	return getSubscriptionErrorStruct(ctx).errs
    69  }
    70  

View as plain text