@@ -300,10 +300,10 @@ func (r *request) addError(err *errors.QueryError) {
300
300
r .mu .Unlock ()
301
301
}
302
302
303
- func (r * request ) handlePanic () {
303
+ func (r * request ) handlePanic (errorHandler errors. ErrorHandler ) {
304
304
if err := recover (); err != nil {
305
305
execErr := errors .Errorf ("graphql: panic occured: %v" , err )
306
- r .addError (execErr )
306
+ r .addError (errorHandler ( execErr ) )
307
307
308
308
const size = 64 << 10
309
309
buf := make ([]byte , size )
@@ -312,10 +312,10 @@ func (r *request) handlePanic() {
312
312
}
313
313
}
314
314
315
- func ExecuteRequest (ctx context.Context , e * Exec , document * query.Document , operationName string , variables map [string ]interface {}) (interface {}, []* errors.QueryError ) {
315
+ func ExecuteRequest (ctx context.Context , e * Exec , document * query.Document , operationName string , variables map [string ]interface {}, errorHandler errors. ErrorHandler ) (interface {}, []* errors.QueryError ) {
316
316
op , err := getOperation (document , operationName )
317
317
if err != nil {
318
- return nil , []* errors.QueryError {errors . Errorf ( "%s" , err )}
318
+ return nil , []* errors.QueryError {errorHandler ( err )}
319
319
}
320
320
321
321
r := & request {
@@ -336,8 +336,8 @@ func ExecuteRequest(ctx context.Context, e *Exec, document *query.Document, oper
336
336
}
337
337
338
338
data := func () interface {} {
339
- defer r .handlePanic ()
340
- return opExec .exec (ctx , r , op .SelSet , e .resolver , serially )
339
+ defer r .handlePanic (errorHandler )
340
+ return opExec .exec (ctx , r , op .SelSet , e .resolver , serially , errorHandler )
341
341
}()
342
342
343
343
return data , r .errs
@@ -365,12 +365,12 @@ func getOperation(document *query.Document, operationName string) (*query.Operat
365
365
}
366
366
367
367
type iExec interface {
368
- exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool ) interface {}
368
+ exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool , errorHander errors. ErrorHandler ) interface {}
369
369
}
370
370
371
371
type scalarExec struct {}
372
372
373
- func (e * scalarExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool ) interface {} {
373
+ func (e * scalarExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool , errorHandler errors. ErrorHandler ) interface {} {
374
374
return resolver .Interface ()
375
375
}
376
376
@@ -379,7 +379,7 @@ type listExec struct {
379
379
nonNull bool
380
380
}
381
381
382
- func (e * listExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool ) interface {} {
382
+ func (e * listExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool , errorHandler errors. ErrorHandler ) interface {} {
383
383
if ! e .nonNull {
384
384
if resolver .IsNil () {
385
385
return nil
@@ -392,8 +392,8 @@ func (e *listExec) exec(ctx context.Context, r *request, selSet *query.Selection
392
392
wg .Add (1 )
393
393
go func (i int ) {
394
394
defer wg .Done ()
395
- defer r .handlePanic ()
396
- l [i ] = e .elem .exec (ctx , r , selSet , resolver .Index (i ), false )
395
+ defer r .handlePanic (errorHandler )
396
+ l [i ] = e .elem .exec (ctx , r , selSet , resolver .Index (i ), false , errorHandler )
397
397
}(i )
398
398
}
399
399
wg .Wait ()
@@ -410,10 +410,10 @@ type objectExec struct {
410
410
411
411
type addResultFn func (key string , value interface {})
412
412
413
- func (e * objectExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool ) interface {} {
413
+ func (e * objectExec ) exec (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , serially bool , errorHandler errors. ErrorHandler ) interface {} {
414
414
if resolver .IsNil () {
415
415
if e .nonNull {
416
- r .addError (errors .Errorf ("got nil for non-null %q" , e .name ))
416
+ r .addError (errorHandler ( fmt .Errorf ("got nil for non-null %q" , e .name ) ))
417
417
}
418
418
return nil
419
419
}
@@ -424,31 +424,31 @@ func (e *objectExec) exec(ctx context.Context, r *request, selSet *query.Selecti
424
424
results [key ] = value
425
425
mu .Unlock ()
426
426
}
427
- e .execSelectionSet (ctx , r , selSet , resolver , addResult , serially )
427
+ e .execSelectionSet (ctx , r , selSet , resolver , addResult , serially , errorHandler )
428
428
return results
429
429
}
430
430
431
- func (e * objectExec ) execSelectionSet (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , addResult addResultFn , serially bool ) {
431
+ func (e * objectExec ) execSelectionSet (ctx context.Context , r * request , selSet * query.SelectionSet , resolver reflect.Value , addResult addResultFn , serially bool , errorHandler errors. ErrorHandler ) {
432
432
var wg sync.WaitGroup
433
433
for _ , sel := range selSet .Selections {
434
434
execSel := func (f func ()) {
435
435
if serially {
436
- defer r .handlePanic ()
436
+ defer r .handlePanic (errorHandler )
437
437
f ()
438
438
return
439
439
}
440
440
441
441
wg .Add (1 )
442
442
go func () {
443
443
defer wg .Done ()
444
- defer r .handlePanic ()
444
+ defer r .handlePanic (errorHandler )
445
445
f ()
446
446
}()
447
447
}
448
448
449
449
switch sel := sel .(type ) {
450
450
case * query.Field :
451
- if ! skipByDirective (r , sel .Directives ) {
451
+ if ! skipByDirective (r , sel .Directives , errorHandler ) {
452
452
f := sel
453
453
execSel (func () {
454
454
switch f .Name {
@@ -467,45 +467,45 @@ func (e *objectExec) execSelectionSet(ctx context.Context, r *request, selSet *q
467
467
}
468
468
469
469
case "__schema" :
470
- addResult (f .Alias , introspectSchema (ctx , r , f .SelSet ))
470
+ addResult (f .Alias , introspectSchema (ctx , r , f .SelSet , errorHandler ))
471
471
472
472
case "__type" :
473
473
p := valuePacker {valueType : stringType }
474
474
v , err := p .pack (r , f .Arguments ["name" ])
475
475
if err != nil {
476
- r .addError (errors . Errorf ( "%s" , err ))
476
+ r .addError (errorHandler ( err ))
477
477
addResult (f .Alias , nil )
478
478
return
479
479
}
480
- addResult (f .Alias , introspectType (ctx , r , v .String (), f .SelSet ))
480
+ addResult (f .Alias , introspectType (ctx , r , v .String (), f .SelSet , errorHandler ))
481
481
482
482
default :
483
483
fe , ok := e .fields [f .Name ]
484
484
if ! ok {
485
485
panic (fmt .Errorf ("%q has no field %q" , e .name , f .Name )) // TODO proper error handling
486
486
}
487
- fe .execField (ctx , r , f , resolver , addResult )
487
+ fe .execField (ctx , r , f , resolver , addResult , errorHandler )
488
488
}
489
489
})
490
490
}
491
491
492
492
case * query.FragmentSpread :
493
- if ! skipByDirective (r , sel .Directives ) {
493
+ if ! skipByDirective (r , sel .Directives , errorHandler ) {
494
494
fs := sel
495
495
execSel (func () {
496
496
frag , ok := r .doc .Fragments [fs .Name ]
497
497
if ! ok {
498
498
panic (fmt .Errorf ("fragment %q not found" , fs .Name )) // TODO proper error handling
499
499
}
500
- e .execFragment (ctx , r , & frag .Fragment , resolver , addResult )
500
+ e .execFragment (ctx , r , & frag .Fragment , resolver , addResult , errorHandler )
501
501
})
502
502
}
503
503
504
504
case * query.InlineFragment :
505
- if ! skipByDirective (r , sel .Directives ) {
505
+ if ! skipByDirective (r , sel .Directives , errorHandler ) {
506
506
frag := sel
507
507
execSel (func () {
508
- e .execFragment (ctx , r , & frag .Fragment , resolver , addResult )
508
+ e .execFragment (ctx , r , & frag .Fragment , resolver , addResult , errorHandler )
509
509
})
510
510
}
511
511
@@ -516,7 +516,7 @@ func (e *objectExec) execSelectionSet(ctx context.Context, r *request, selSet *q
516
516
wg .Wait ()
517
517
}
518
518
519
- func (e * objectExec ) execFragment (ctx context.Context , r * request , frag * query.Fragment , resolver reflect.Value , addResult addResultFn ) {
519
+ func (e * objectExec ) execFragment (ctx context.Context , r * request , frag * query.Fragment , resolver reflect.Value , addResult addResultFn , errorHandler errors. ErrorHandler ) {
520
520
if frag .On != "" && frag .On != e .name {
521
521
a , ok := e .typeAssertions [frag .On ]
522
522
if ! ok {
@@ -526,10 +526,10 @@ func (e *objectExec) execFragment(ctx context.Context, r *request, frag *query.F
526
526
if ! out [1 ].Bool () {
527
527
return
528
528
}
529
- a .typeExec .(* objectExec ).execSelectionSet (ctx , r , frag .SelSet , out [0 ], addResult , false )
529
+ a .typeExec .(* objectExec ).execSelectionSet (ctx , r , frag .SelSet , out [0 ], addResult , false , errorHandler )
530
530
return
531
531
}
532
- e .execSelectionSet (ctx , r , frag .SelSet , resolver , addResult , false )
532
+ e .execSelectionSet (ctx , r , frag .SelSet , resolver , addResult , false , errorHandler )
533
533
}
534
534
535
535
type fieldExec struct {
@@ -542,7 +542,7 @@ type fieldExec struct {
542
542
valueExec iExec
543
543
}
544
544
545
- func (e * fieldExec ) execField (ctx context.Context , r * request , f * query.Field , resolver reflect.Value , addResult addResultFn ) {
545
+ func (e * fieldExec ) execField (ctx context.Context , r * request , f * query.Field , resolver reflect.Value , addResult addResultFn , errorHandler errors. ErrorHandler ) {
546
546
span , spanCtx := opentracing .StartSpanFromContext (ctx , fmt .Sprintf ("GraphQL field: %s.%s" , e .typeName , e .field .Name ))
547
547
defer span .Finish ()
548
548
span .SetTag (OpenTracingTagType , e .typeName )
@@ -551,10 +551,10 @@ func (e *fieldExec) execField(ctx context.Context, r *request, f *query.Field, r
551
551
span .SetTag (OpenTracingTagTrivial , true )
552
552
}
553
553
554
- result , err := e .execField2 (spanCtx , r , f , resolver , span )
554
+ result , err := e .execField2 (spanCtx , r , f , resolver , span , errorHandler )
555
555
556
556
if err != nil {
557
- r .addError (errors . Errorf ( "%s" , err ))
557
+ r .addError (errorHandler ( err ))
558
558
addResult (f .Alias , nil ) // TODO handle non-nil
559
559
560
560
ext .Error .Set (span , true )
@@ -565,7 +565,7 @@ func (e *fieldExec) execField(ctx context.Context, r *request, f *query.Field, r
565
565
addResult (f .Alias , result )
566
566
}
567
567
568
- func (e * fieldExec ) execField2 (ctx context.Context , r * request , f * query.Field , resolver reflect.Value , span opentracing.Span ) (interface {}, error ) {
568
+ func (e * fieldExec ) execField2 (ctx context.Context , r * request , f * query.Field , resolver reflect.Value , span opentracing.Span , errorHandler errors. ErrorHandler ) (interface {}, error ) {
569
569
var in []reflect.Value
570
570
571
571
if e .hasContext {
@@ -589,20 +589,20 @@ func (e *fieldExec) execField2(ctx context.Context, r *request, f *query.Field,
589
589
return nil , out [1 ].Interface ().(error )
590
590
}
591
591
592
- return e .valueExec .exec (ctx , r , f .SelSet , out [0 ], false ), nil
592
+ return e .valueExec .exec (ctx , r , f .SelSet , out [0 ], false , errorHandler ), nil
593
593
}
594
594
595
595
type typeAssertExec struct {
596
596
methodIndex int
597
597
typeExec iExec
598
598
}
599
599
600
- func skipByDirective (r * request , d map [string ]* query.Directive ) bool {
600
+ func skipByDirective (r * request , d map [string ]* query.Directive , errorHandler errors. ErrorHandler ) bool {
601
601
if skip , ok := d ["skip" ]; ok {
602
602
p := valuePacker {valueType : boolType }
603
603
v , err := p .pack (r , skip .Arguments ["if" ])
604
604
if err != nil {
605
- r .addError (errors . Errorf ( "%s" , err ))
605
+ r .addError (errorHandler ( err ))
606
606
}
607
607
if err == nil && v .Bool () {
608
608
return true
@@ -613,7 +613,7 @@ func skipByDirective(r *request, d map[string]*query.Directive) bool {
613
613
p := valuePacker {valueType : boolType }
614
614
v , err := p .pack (r , include .Arguments ["if" ])
615
615
if err != nil {
616
- r .addError (errors . Errorf ( "%s" , err ))
616
+ r .addError (errorHandler ( err ))
617
617
}
618
618
if err == nil && ! v .Bool () {
619
619
return true
0 commit comments