Repository: honeydipper/honeydipper
Pull request #521 (2023-03-01 18:10:22)

feat: allow export on error
#### Description
Export on error was previously ignored. However, it is found
to be important to be able to use export on error to construct
meaningful data and messages for subsequential operations. This
should make it possible to do that.

add test for export and export_on_error

#### This PR fixes the following issues




Patch:
diff --git a/internal/config/schema.go b/internal/config/schema.go
index 046b1a8..4f19a51 100644
--- a/internal/config/schema.go
+++ b/internal/config/schema.go
@@ -103,6 +103,7 @@ type Workflow struct {
 	Export          map[string]interface{}
 	ExportOnSuccess map[string]interface{} `json:"export_on_success" mapstructure:"export_on_success"`
 	ExportOnFailure map[string]interface{} `json:"export_on_failure" mapstructure:"export_on_failure"`
+	ExportOnError   map[string]interface{} `json:"export_on_error" mapstructure:"export_on_error"`
 	NoExport        []string               `json:"no_export" mapstructure:"no_export"`
 }
 
diff --git a/internal/workflow/continue.go b/internal/workflow/continue.go
index 68fd775..3d6da35 100644
--- a/internal/workflow/continue.go
+++ b/internal/workflow/continue.go
@@ -137,6 +137,8 @@ func (w *Session) processExport(msg *dipper.Message) {
 	}
 	if status != SessionStatusError {
 		w.postWorkflowExport(w.workflow.Export, envData)
+	} else {
+		w.postWorkflowExport(w.workflow.ExportOnError, envData)
 	}
 	if status == SessionStatusSuccess {
 		w.postWorkflowExport(w.workflow.ExportOnSuccess, envData)
diff --git a/internal/workflow/session.go b/internal/workflow/session.go
index e793353..7b408e9 100644
--- a/internal/workflow/session.go
+++ b/internal/workflow/session.go
@@ -320,6 +320,7 @@ func (w *Session) interpolateWorkflow(msg *dipper.Message) {
 	ret.Export = v.Export                   // delayed
 	ret.ExportOnSuccess = v.ExportOnSuccess // delayed
 	ret.ExportOnFailure = v.ExportOnFailure // delayed
+	ret.ExportOnError = v.ExportOnError     // delayed
 	ret.Switch = v.Switch                   // delayed
 	ret.Cases = v.Cases                     // delayed
 	ret.Default = v.Default                 // delayed


Test patch:
diff --git a/internal/workflow/session_context_test.go b/internal/workflow/session_context_test.go
index fc3bde4..4c29623 100644
--- a/internal/workflow/session_context_test.go
+++ b/internal/workflow/session_context_test.go
@@ -98,6 +98,17 @@ contexts:
 	exported = map[string]interface{}{"data1": "testdata"}
 	w.processNoExport(exported)
 	assert.Empty(t, exported, "remove all items from exported data")
+
+	w = s.newSession("", "uuid10", &config.Workflow{Name: "workflow1", ExportOnError: map[string]interface{}{"foo": "bar"}, Export: map[string]interface{}{"foo2": "bar2"}}).(*Session)
+	w.prepare(&dipper.Message{}, nil, map[string]interface{}{})
+	w.processExport(&dipper.Message{
+		Labels: map[string]string{
+			"status": "error",
+			"reason": "test",
+		},
+	})
+	assert.Equal(t, "bar", w.exported[0]["foo"], "export_on_error should be used if on error")
+	assert.NotContains(t, w.exported[0], "foo2", "export should not be used if on error")
 }
 
 var configStrWithEventContexts = `