diff --git a/pkg/worker/workflow.go b/pkg/worker/workflow.go index 8b187f5f5..d9ca72699 100644 --- a/pkg/worker/workflow.go +++ b/pkg/worker/workflow.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "github.com/Southclaws/fault" + "github.com/Southclaws/fault/fmsg" "github.com/gofrs/uuid" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" @@ -632,7 +634,7 @@ func (w *worker) ConnectorActivity(ctx context.Context, param *ExecuteConnectorA } compOutputs, err := execution.ExecuteWithValidation(compInputs) if err != nil { - return nil, fmt.Errorf("[Component %s Execution Data Error] %s", param.Id, status.Convert(err).Message()) + return nil, w.toExecutionError(err, param.Id) } outputBlobRedisKeys, err := w.SetBlob(compOutputs) @@ -665,7 +667,7 @@ func (w *worker) OperatorActivity(ctx context.Context, param *ExecuteOperatorAct } compOutputs, err := execution.ExecuteWithValidation(compInputs) if err != nil { - return nil, fmt.Errorf("[Component %s Execution Data Error] %s", param.Id, status.Convert(err).Message()) + return nil, w.toExecutionError(err, param.Id) } outputBlobRedisKeys, err := w.SetBlob(compOutputs) @@ -676,3 +678,16 @@ func (w *worker) OperatorActivity(ctx context.Context, param *ExecuteOperatorAct logger.Info("OperatorActivity completed") return &ExecuteOperatorActivityResponse{OutputBlobRedisKeys: outputBlobRedisKeys}, nil } + +// toExecutionError adds end-user information to the error. +func (w *worker) toExecutionError(err error, id string) error { + if fmsg.GetIssue(err) == "" { + // If the underlying component doesn't provide an end-user message, we + // return the raw error, as exposing the implementation details is + // more actionable than hiding the error. + return fmt.Errorf("[Component %s Execution Data Error] %s", id, status.Convert(err).Message()) + } + + issue := fmt.Sprintf("Component %s failed to execute.", id) + return fault.Wrap(err, fmsg.WithDesc("component failed to execute", issue)) +}