diff --git a/cmd/root/root.go b/cmd/root/root.go index b73fd5bb..1cca142e 100644 --- a/cmd/root/root.go +++ b/cmd/root/root.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/databricks/bricks/internal/build" + "github.com/databricks/bricks/libs/cmdio" "github.com/databricks/bricks/libs/log" "github.com/spf13/cobra" "golang.org/x/exp/slog" @@ -23,6 +24,9 @@ var RootCmd = &cobra.Command{ // The usage string is include in [flagErrorFunc] for flag errors only. SilenceUsage: true, + // Silence error printing by cobra. Errors are printed through cmdio. + SilenceErrors: true, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() @@ -64,6 +68,11 @@ func Execute() { // Run the command cmd, err := RootCmd.ExecuteContextC(ctx) + if err != nil { + // If cmdio logger initialization succeeds, then this function logs with the + // initialized cmdio logger, otherwise with the default cmdio logger + cmdio.LogError(cmd.Context(), err) + } // Log exit status and error // We only log if logger initialization succeeded and is stored in command diff --git a/libs/cmdio/error_event.go b/libs/cmdio/error_event.go new file mode 100644 index 00000000..933f9d0d --- /dev/null +++ b/libs/cmdio/error_event.go @@ -0,0 +1,15 @@ +package cmdio + +import "fmt" + +type ErrorEvent struct { + Error string `json:"error"` +} + +func (event *ErrorEvent) String() string { + return fmt.Sprintf("Error: %s", event.Error) +} + +func (event *ErrorEvent) IsInplaceSupported() bool { + return false +} diff --git a/libs/cmdio/logger.go b/libs/cmdio/logger.go index 8904ddd7..7afa81fc 100644 --- a/libs/cmdio/logger.go +++ b/libs/cmdio/logger.go @@ -64,6 +64,16 @@ func LogString(ctx context.Context, message string) { }) } +func LogError(ctx context.Context, err error) { + logger, ok := FromContext(ctx) + if !ok { + logger = Default() + } + logger.Log(&ErrorEvent{ + Error: err.Error(), + }) +} + func Ask(ctx context.Context, question string) (bool, error) { logger, ok := FromContext(ctx) if !ok {