Home >Backend Development >Golang >Context retrieved from cobra subcommand is empty
I want a global timeout (set in rootCmd
), so I set it in rootCmd
is set as follows
ctxInit := context.Background() timeout := viper.GetInt("timeout") ctx, cancel := context.WithTimeout(ctxInit, time.Duration(timeout)*time.Second) defer cancel() cmd.SetContext(ctx)
Then in the subcommand
ctx := rootCmd.Context()
But ctx
is context.emptyCtx {}
Am I doing something wrong in setting/retrieving the context?
edit
My rootCmd
Statement
// rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "my-cli", TraverseChildren: true, Short: "cli", PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { var err error logger, err = logging.InitialiseLogger(*logLevel, *logFormat) if err != nil { return err } if err := viper.BindPFlags(cmd.Flags()); err != nil { return fmt.Errorf("error binding flags to %s command: %w\n", cmd.Name(), err) } if err := cloneMethodValidator(cmd); err != nil { return err } if err := InitConfig(false); err != nil { logger.Fatal("ERROR initiating configuration:\n", err) } ctxInit := context.Background() timeout := viper.GetInt("timeout") ctx, cancel := context.WithTimeout(ctxInit, time.Duration(timeout)*time.Second) defer cancel() cmd.SetContext(ctx) return nil }, }
As @Peter mentioned, cmd and rootCmd are not the same. The Cobra documentation describes PersistentPreRun(E)
:
So cmd.SetContext(ctx)
does not set the context of rootCmd, but sets the context of the subcommand.
Then in the subcommand you can use:
ctx := cmd.Context()
instead of rootCmd.Context()
.
The above is the detailed content of Context retrieved from cobra subcommand is empty. For more information, please follow other related articles on the PHP Chinese website!