Fix panic in GraphQL resolver not hit httpserver recover

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-25 07:04:04 +01:00
parent 4b828d3947
commit cc7c1db6c3
2 changed files with 15 additions and 8 deletions

View File

@@ -15,7 +15,6 @@ resolver:
filename_template: "v1_resolver.go" filename_template: "v1_resolver.go"
autobind: [] autobind: []
omit_panic_handler: true
call_argument_directives_with_null: true call_argument_directives_with_null: true
models: models:

View File

@@ -59,6 +59,7 @@ var (
sessionContextKey = &ctxKey{name: "session"} sessionContextKey = &ctxKey{name: "session"}
userContextKey = &ctxKey{name: "user"} userContextKey = &ctxKey{name: "user"}
userTenantContextKey = &ctxKey{name: "user_tenants"} userTenantContextKey = &ctxKey{name: "user_tenants"}
panicValueContextKey = &ctxKey{name: "panic_value"}
) )
func SessionFromContext(ctx context.Context) *coredata.Session { func SessionFromContext(ctx context.Context) *coredata.Session {
@@ -108,14 +109,12 @@ 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( panicValue := ctx.Value(panicValueContextKey).(*any)
func(ctx context.Context, err any) error { *panicValue = err
panic(fmt.Errorf("graphql resolver panic: %v", err)) return fmt.Errorf("resolver panic: %v", err)
}, })
)
srv.AroundOperations( srv.AroundOperations(
func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
@@ -143,6 +142,11 @@ func graphqlHandler(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() 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)
cookieValue, err := securecookie.Get(r, securecookie.DefaultConfig( cookieValue, err := securecookie.Get(r, securecookie.DefaultConfig(
authCfg.CookieName, authCfg.CookieName,
authCfg.CookieSecret, authCfg.CookieSecret,
@@ -200,6 +204,10 @@ func graphqlHandler(proboSvc *probo.Service, usrmgrSvc *usrmgr.Service, authCfg
srv.ServeHTTP(w, r.WithContext(ctx)) srv.ServeHTTP(w, r.WithContext(ctx))
if panicValue != nil {
panic(panicValue)
}
if err := usrmgrSvc.UpdateSession(r.Context(), session); err != nil { if err := usrmgrSvc.UpdateSession(r.Context(), session); err != nil {
panic(fmt.Errorf("failed to update session: %w", err)) panic(fmt.Errorf("failed to update session: %w", err))
} }