1package graphql
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "io"
8 "strings"
9
10 "github.com/99designs/gqlgen/graphql"
11
12 "github.com/git-bug/git-bug/util/colors"
13)
14
15// adapted from https://github.com/99designs/gqlgen/blob/master/graphql/handler/debug/tracer.go
16
17var _ graphql.HandlerExtension = &Tracer{}
18var _ graphql.ResponseInterceptor = &Tracer{}
19
20type Tracer struct {
21 Out io.Writer
22}
23
24func (a Tracer) ExtensionName() string {
25 return "error tracer"
26}
27
28func (a Tracer) Validate(schema graphql.ExecutableSchema) error {
29 return nil
30}
31
32func (a Tracer) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
33 resp := next(ctx)
34
35 if len(resp.Errors) == 0 {
36 return resp
37 }
38
39 rctx := graphql.GetOperationContext(ctx)
40
41 _, _ = fmt.Fprintln(a.Out, "GraphQL Request {")
42 for _, line := range strings.Split(rctx.RawQuery, "\n") {
43 _, _ = fmt.Fprintln(a.Out, " ", colors.Cyan(line))
44 }
45 for name, value := range rctx.Variables {
46 _, _ = fmt.Fprintf(a.Out, " var %s = %s\n", name, colors.Yellow(stringify(value)))
47 }
48
49 _, _ = fmt.Fprintln(a.Out, " resp:", colors.Green(stringify(resp)))
50 for _, err := range resp.Errors {
51 _, _ = fmt.Fprintln(a.Out, " error:", colors.Bold(err.Path.String()+":"), colors.Red(err.Message))
52 }
53 _, _ = fmt.Fprintln(a.Out, "}")
54 _, _ = fmt.Fprintln(a.Out)
55 return resp
56}
57
58func stringify(value interface{}) string {
59 valueJson, err := json.MarshalIndent(value, " ", " ")
60 if err == nil {
61 return string(valueJson)
62 }
63
64 return fmt.Sprint(value)
65}