From 8d11e620a3d663cf21a62910d0f3961a8aff4be1 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Tue, 23 Aug 2022 15:02:41 +0200 Subject: webui: add a flag to log handling errors --- api/graphql/graphql_test.go | 2 +- api/graphql/handler.go | 6 +++- api/graphql/tracer.go | 67 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 api/graphql/tracer.go (limited to 'api') diff --git a/api/graphql/graphql_test.go b/api/graphql/graphql_test.go index 350e489a..2ddfb314 100644 --- a/api/graphql/graphql_test.go +++ b/api/graphql/graphql_test.go @@ -22,7 +22,7 @@ func TestQueries(t *testing.T) { _, err := mrc.RegisterDefaultRepository(repo) require.NoError(t, err) - handler := NewHandler(mrc) + handler := NewHandler(mrc, nil) c := client.New(handler) diff --git a/api/graphql/handler.go b/api/graphql/handler.go index 00141f01..1d30bf72 100644 --- a/api/graphql/handler.go +++ b/api/graphql/handler.go @@ -20,11 +20,15 @@ type Handler struct { io.Closer } -func NewHandler(mrc *cache.MultiRepoCache) Handler { +func NewHandler(mrc *cache.MultiRepoCache, errorOut io.Writer) Handler { rootResolver := resolvers.NewRootResolver(mrc) config := graph.Config{Resolvers: rootResolver} h := handler.NewDefaultServer(graph.NewExecutableSchema(config)) + if errorOut != nil { + h.Use(&Tracer{Out: errorOut}) + } + return Handler{ Handler: h, Closer: rootResolver, diff --git a/api/graphql/tracer.go b/api/graphql/tracer.go new file mode 100644 index 00000000..11448a3a --- /dev/null +++ b/api/graphql/tracer.go @@ -0,0 +1,67 @@ +package graphql + +import ( + "context" + "encoding/json" + "fmt" + "io" + "strings" + + "github.com/99designs/gqlgen/graphql" + + "github.com/MichaelMure/git-bug/util/colors" +) + +// adapted from https://github.com/99designs/gqlgen/blob/master/graphql/handler/debug/tracer.go + +type Tracer struct { + Out io.Writer +} + +var _ interface { + graphql.HandlerExtension + graphql.ResponseInterceptor +} = &Tracer{} + +func (a Tracer) ExtensionName() string { + return "error tracer" +} + +func (a *Tracer) Validate(schema graphql.ExecutableSchema) error { + return nil +} + +func stringify(value interface{}) string { + valueJson, err := json.MarshalIndent(value, " ", " ") + if err == nil { + return string(valueJson) + } + + return fmt.Sprint(value) +} + +func (a Tracer) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + resp := next(ctx) + + if len(resp.Errors) == 0 { + return resp + } + + rctx := graphql.GetOperationContext(ctx) + + _, _ = fmt.Fprintln(a.Out, "GraphQL Request {") + for _, line := range strings.Split(rctx.RawQuery, "\n") { + _, _ = fmt.Fprintln(a.Out, " ", colors.Cyan(line)) + } + for name, value := range rctx.Variables { + _, _ = fmt.Fprintf(a.Out, " var %s = %s\n", name, colors.Yellow(stringify(value))) + } + + _, _ = fmt.Fprintln(a.Out, " resp:", colors.Green(stringify(resp))) + for _, err := range resp.Errors { + _, _ = fmt.Fprintln(a.Out, " error:", colors.Bold(err.Path.String()+":"), colors.Red(err.Message)) + } + _, _ = fmt.Fprintln(a.Out, "}") + _, _ = fmt.Fprintln(a.Out) + return resp +} -- cgit