Log graphql error

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2025-05-16 20:40:16 -07:00
parent 366fd9ea08
commit 0ea848ed8a
4 changed files with 31 additions and 20 deletions

View File

@@ -217,6 +217,7 @@ func (impl *Implm) Run(
Usrmgr: usrmgrService, Usrmgr: usrmgrService,
ConnectorRegistry: defaultConnectorRegistry, ConnectorRegistry: defaultConnectorRegistry,
SafeRedirect: &saferedirect.SafeRedirect{AllowedHost: impl.cfg.Hostname}, SafeRedirect: &saferedirect.SafeRedirect{AllowedHost: impl.cfg.Hostname},
Logger: l.Named("http.server"),
Auth: console_v1.AuthConfig{ Auth: console_v1.AuthConfig{
CookieName: impl.cfg.Auth.Cookie.Name, CookieName: impl.cfg.Auth.Cookie.Name,
CookieDomain: impl.cfg.Auth.Cookie.Domain, CookieDomain: impl.cfg.Auth.Cookie.Domain,

View File

@@ -26,6 +26,7 @@ import (
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/go-chi/cors" "github.com/go-chi/cors"
"go.gearno.de/kit/httpserver" "go.gearno.de/kit/httpserver"
"go.gearno.de/kit/log"
) )
type ( type (
@@ -36,6 +37,7 @@ type (
Auth console_v1.AuthConfig Auth console_v1.AuthConfig
ConnectorRegistry *connector.ConnectorRegistry ConnectorRegistry *connector.ConnectorRegistry
SafeRedirect *saferedirect.SafeRedirect SafeRedirect *saferedirect.SafeRedirect
Logger *log.Logger
} }
Server struct { Server struct {
@@ -105,7 +107,17 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
router.Use(cors.Handler(corsOpts)) router.Use(cors.Handler(corsOpts))
// Mount the console API with authentication // Mount the console API with authentication
router.Mount("/console/v1", console_v1.NewMux(s.cfg.Probo, s.cfg.Usrmgr, s.cfg.Auth, s.cfg.ConnectorRegistry, s.cfg.SafeRedirect)) router.Mount(
"/console/v1",
console_v1.NewMux(
s.cfg.Logger.Named("console.v1"),
s.cfg.Probo,
s.cfg.Usrmgr,
s.cfg.Auth,
s.cfg.ConnectorRegistry,
s.cfg.SafeRedirect,
),
)
router.ServeHTTP(w, r) router.ServeHTTP(w, r)
} }

View File

@@ -41,6 +41,7 @@ import (
"github.com/getprobo/probo/pkg/usrmgr" "github.com/getprobo/probo/pkg/usrmgr"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/vektah/gqlparser/v2/gqlerror" "github.com/vektah/gqlparser/v2/gqlerror"
"go.gearno.de/kit/log"
) )
type ( type (
@@ -77,7 +78,14 @@ func UserFromContext(ctx context.Context) *coredata.User {
return user return user
} }
func NewMux(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg AuthConfig, connectorRegistry *connector.ConnectorRegistry, safeRedirect *saferedirect.SafeRedirect) *chi.Mux { func NewMux(
logger *log.Logger,
proboSvc *probo.Service,
usrmgrSvc *usrmgr.Service,
authCfg AuthConfig,
connectorRegistry *connector.ConnectorRegistry,
safeRedirect *saferedirect.SafeRedirect,
) *chi.Mux {
r := chi.NewMux() r := chi.NewMux()
r.Get( r.Get(
@@ -197,12 +205,12 @@ func NewMux(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg AuthConf
})) }))
r.Get("/", playground.Handler("GraphQL", "/api/console/v1/query")) r.Get("/", playground.Handler("GraphQL", "/api/console/v1/query"))
r.Post("/query", graphqlHandler(proboSvc, usrmgrSvc, authCfg)) r.Post("/query", graphqlHandler(logger, proboSvc, usrmgrSvc, authCfg))
return r return r
} }
func graphqlHandler(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg AuthConfig) http.HandlerFunc { func graphqlHandler(logger *log.Logger, proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg AuthConfig) http.HandlerFunc {
var mb int64 = 1 << 20 var mb int64 = 1 << 20
es := schema.NewExecutableSchema( es := schema.NewExecutableSchema(
@@ -225,8 +233,8 @@ func graphqlHandler(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg
srv.Use(extension.Introspection{}) srv.Use(extension.Introspection{})
srv.Use(tracingExtension{}) srv.Use(tracingExtension{})
srv.SetRecoverFunc(func(ctx context.Context, err any) error { srv.SetRecoverFunc(func(ctx context.Context, err any) error {
panicValue := ctx.Value(panicValueContextKey).(*any) logger.Error("resolver panic", log.Any("error", err))
*panicValue = err
return fmt.Errorf("resolver panic: %v", err) return fmt.Errorf("resolver panic: %v", err)
}) })
@@ -253,20 +261,7 @@ func graphqlHandler(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg
}, },
) )
return WithSession(usrmgrSvc, authCfg, func(w http.ResponseWriter, r *http.Request) { return WithSession(usrmgrSvc, authCfg, srv.ServeHTTP)
ctx := r.Context()
// Hack to capture the panic value, because gqlgen execute resolver in a different goroutine.
// And I want use the go.gearno.de/kit/httpserver built in panic recovery.
var panicValue any
ctx = context.WithValue(ctx, panicValueContextKey, &panicValue)
srv.ServeHTTP(w, r.WithContext(ctx))
if panicValue != nil {
panic(panicValue)
}
})
} }
func WithSession(usrmgrSvc *usrmgr.Service, authCfg AuthConfig, next http.HandlerFunc) http.HandlerFunc { func WithSession(usrmgrSvc *usrmgr.Service, authCfg AuthConfig, next http.HandlerFunc) http.HandlerFunc {

View File

@@ -27,6 +27,7 @@ import (
"github.com/getprobo/probo/pkg/server/web" "github.com/getprobo/probo/pkg/server/web"
"github.com/getprobo/probo/pkg/usrmgr" "github.com/getprobo/probo/pkg/usrmgr"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"go.gearno.de/kit/log"
) )
// Config holds the configuration for the server // Config holds the configuration for the server
@@ -37,6 +38,7 @@ type Config struct {
Auth console_v1.AuthConfig Auth console_v1.AuthConfig
ConnectorRegistry *connector.ConnectorRegistry ConnectorRegistry *connector.ConnectorRegistry
SafeRedirect *saferedirect.SafeRedirect SafeRedirect *saferedirect.SafeRedirect
Logger *log.Logger
} }
// Server represents the main server that handles both API and frontend requests // Server represents the main server that handles both API and frontend requests
@@ -56,6 +58,7 @@ func NewServer(cfg Config) (*Server, error) {
Auth: cfg.Auth, Auth: cfg.Auth,
ConnectorRegistry: cfg.ConnectorRegistry, ConnectorRegistry: cfg.ConnectorRegistry,
SafeRedirect: cfg.SafeRedirect, SafeRedirect: cfg.SafeRedirect,
Logger: cfg.Logger.Named("api"),
} }
apiServer, err := api.NewServer(apiCfg) apiServer, err := api.NewServer(apiCfg)
if err != nil { if err != nil {