@flowlab/all
Version:
A cool library focusing on handling various flows
546 lines (545 loc) • 34.8 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkflowExecutor = void 0;
var runtime_1 = require("../types/runtime");
var config_1 = require("../types/config");
var context_1 = require("./context"); // Assuming these exist
var index_1 = require("../errors/index");
var WorkflowExecutor = /** @class */ (function () {
function WorkflowExecutor(options) {
var _a;
this.nodeRegistry = options.nodeRegistry;
this.logger = options.logger;
this.persistence = options.persistence;
this.scheduler = options.scheduler;
this.eventManager = options.eventManager;
this.getWorkflowDefinition = options.getWorkflowDefinition;
this.maxLoopIterations = (_a = options.maxLoopIterations) !== null && _a !== void 0 ? _a : 1000;
}
WorkflowExecutor.prototype.run = function (definitionOrId_1, input_1) {
return __awaiter(this, arguments, void 0, function (definitionOrId, input, contextExtras) {
var definition, _a, context, currentStepId, loopGuard, stepConfig, stepResult, error_1, saveError_1;
var _b;
if (contextExtras === void 0) { contextExtras = {}; }
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!(typeof definitionOrId === 'string')) return [3 /*break*/, 2];
return [4 /*yield*/, this.getWorkflowDefinition(definitionOrId)];
case 1:
_a = _c.sent();
return [3 /*break*/, 3];
case 2:
_a = definitionOrId;
_c.label = 3;
case 3:
definition = _a;
if (!definition) {
throw new index_1.ConfigurationError("Workflow definition '".concat(definitionOrId, "' not found."));
}
if (!definition.startStepId) {
throw new index_1.ConfigurationError("Workflow definition '".concat(definition.id, "' has no start step defined."));
}
if (!definition.validate()) { // Added validation call
throw new index_1.ConfigurationError("Workflow definition '".concat(definition.id, "' failed validation."));
}
context = (0, context_1.createWorkflowContext)(definition.id, definition.name, input, contextExtras);
this.logger.info("Starting workflow run: ".concat(context.workflowId, " (Def: ").concat(definition.id, ")"));
return [4 /*yield*/, this.emitEvent('workflow.started', context)];
case 4:
_c.sent(); // Emit event
currentStepId = definition.startStepId;
loopGuard = 0;
_c.label = 5;
case 5:
_c.trys.push([5, 15, 17, 22]);
_c.label = 6;
case 6:
if (!(currentStepId && loopGuard++ < this.maxLoopIterations)) return [3 /*break*/, 14];
stepConfig = definition.getStep(currentStepId);
if (!stepConfig) {
throw new index_1.WorkflowError("Step '".concat(currentStepId, "' not found in workflow '").concat(definition.id, "'."), context.workflowId);
}
context.logs.push("Executing step: ".concat(currentStepId, " (Type: ").concat(stepConfig.type, ")"));
return [4 /*yield*/, this.executeStep(stepConfig, context)];
case 7:
stepResult = _c.sent();
// Update history and persistence
this.updateHistory(context, stepResult.record);
if (!this.persistence) return [3 /*break*/, 9];
return [4 /*yield*/, this.persistence.saveState(context)];
case 8:
_c.sent();
_c.label = 9;
case 9:
if (!(stepResult.status === runtime_1.NodeStatus.FAILED || stepResult.status === runtime_1.NodeStatus.CANCELLED)) return [3 /*break*/, 11];
context.status = stepResult.status;
context.output = stepResult.output; // Capture last output on failure
this.logger.error("Workflow run ".concat(context.workflowId, " failed at step ").concat(currentStepId, "."), stepResult.error);
return [4 /*yield*/, this.emitEvent('workflow.failed', context, { stepId: currentStepId, error: (_b = stepResult.error) === null || _b === void 0 ? void 0 : _b.message })];
case 10:
_c.sent();
return [3 /*break*/, 14]; // Stop execution
case 11:
if (stepResult.status === runtime_1.NodeStatus.COMPENSATING) {
// TODO: Implement compensation flow triggering
this.logger.warn("Compensation requested at step ".concat(currentStepId, ", stopping normal flow."));
context.status = runtime_1.NodeStatus.FAILED; // Mark workflow as failed if compensation needed? Or specific status?
return [3 /*break*/, 14];
}
currentStepId = stepResult.nextStepId; // Determine next step
if (!!currentStepId) return [3 /*break*/, 13];
context.status = runtime_1.NodeStatus.COMPLETED;
context.output = stepResult.output; // Capture final output
this.logger.info("Workflow run ".concat(context.workflowId, " completed successfully."));
return [4 /*yield*/, this.emitEvent('workflow.completed', context)];
case 12:
_c.sent();
return [3 /*break*/, 14]; // Workflow finished
case 13: return [3 /*break*/, 6];
case 14:
if (loopGuard >= this.maxLoopIterations) {
throw new index_1.WorkflowError("Maximum loop iterations (".concat(this.maxLoopIterations, ") reached. Potential infinite loop detected."), context.workflowId);
}
return [3 /*break*/, 22];
case 15:
error_1 = _c.sent();
context.status = runtime_1.NodeStatus.FAILED;
context.error = error_1; // Store workflow-level error
this.logger.error("Workflow run ".concat(context.workflowId, " encountered an unhandled error."), error_1);
return [4 /*yield*/, this.emitEvent('workflow.failed', context, { error: error_1.message })];
case 16:
_c.sent();
return [3 /*break*/, 22];
case 17:
context.endTime = new Date();
if (!this.persistence) return [3 /*break*/, 21];
_c.label = 18;
case 18:
_c.trys.push([18, 20, , 21]);
return [4 /*yield*/, this.persistence.saveState(context)];
case 19:
_c.sent(); // Final state save
return [3 /*break*/, 21];
case 20:
saveError_1 = _c.sent();
this.logger.error("Failed to save final workflow state for ".concat(context.workflowId), saveError_1);
return [3 /*break*/, 21];
case 21: return [7 /*endfinally*/];
case 22: return [2 /*return*/, context];
}
});
});
};
// --- Step Execution Logic (Needs detailed implementation) ---
WorkflowExecutor.prototype.executeStep = function (stepConfig, workflowContext) {
return __awaiter(this, void 0, void 0, function () {
var stepStartTime, stepStatus, stepOutput, stepError, nextStepId, record, _a, taskResult, conditionResult, err_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
stepStartTime = new Date();
stepStatus = runtime_1.NodeStatus.PENDING;
stepOutput = undefined;
stepError = undefined;
nextStepId = stepConfig.nextStepId;
record = {
stepId: stepConfig.id,
startTime: stepStartTime,
status: runtime_1.NodeStatus.PENDING,
};
_b.label = 1;
case 1:
_b.trys.push([1, 11, 12, 14]);
return [4 /*yield*/, this.emitEvent('step.started', workflowContext, { stepId: stepConfig.id, type: stepConfig.type })];
case 2:
_b.sent();
stepStatus = runtime_1.NodeStatus.RUNNING;
record.status = stepStatus; // Update record status
_a = stepConfig.type;
switch (_a) {
case config_1.StepType.TASK: return [3 /*break*/, 3];
case config_1.StepType.CONDITION: return [3 /*break*/, 5];
case config_1.StepType.PARALLEL: return [3 /*break*/, 7];
case config_1.StepType.SUB_WORKFLOW: return [3 /*break*/, 8];
}
return [3 /*break*/, 9];
case 3: return [4 /*yield*/, this.executeTaskStep(stepConfig, workflowContext)];
case 4:
taskResult = _b.sent();
stepStatus = taskResult.status;
stepOutput = taskResult.output;
stepError = taskResult.error;
record.nodeId = stepConfig.nodeId;
// Use default nextStepId unless overridden
return [3 /*break*/, 10];
case 5: return [4 /*yield*/, this.executeConditionStep(stepConfig, workflowContext)];
case 6:
conditionResult = _b.sent();
stepStatus = runtime_1.NodeStatus.COMPLETED; // Condition itself completes
nextStepId = conditionResult.nextStepId; // Condition determines the *actual* next step
record.output = { branchTaken: conditionResult.branchKey }; // Record which branch was taken
if (!nextStepId) { // No matching branch, potentially end workflow if this was the last path
this.logger.warn("Condition step '".concat(stepConfig.id, "' resulted in no matching branch ('").concat(conditionResult.branchKey, "'). Ending this path."));
}
return [3 /*break*/, 10];
case 7:
// TODO: Implement parallel execution logic
// This involves running multiple steps concurrently and waiting for all.
// Needs careful state management and error handling for partial failures.
this.logger.warn("Parallel step execution not fully implemented yet for step: ".concat(stepConfig.id));
stepStatus = runtime_1.NodeStatus.SKIPPED; // Mark as skipped for now
return [3 /*break*/, 10];
case 8:
// TODO: Implement sub-workflow execution
// Needs to call executor.run() recursively with the sub-workflow def/id
// and handle input/output mapping.
this.logger.warn("SubWorkflow step execution not fully implemented yet for step: ".concat(stepConfig.id));
stepStatus = runtime_1.NodeStatus.SKIPPED; // Mark as skipped for now
return [3 /*break*/, 10];
case 9: throw new index_1.ConfigurationError("Unsupported step type: ".concat(stepConfig.type));
case 10:
if (stepStatus === runtime_1.NodeStatus.FAILED && stepConfig.compensateOnFailure) {
// TODO: Trigger compensation logic
this.logger.warn("Compensation requested for failed step '".concat(stepConfig.id, "'. Compensation logic not fully implemented."));
// Potentially change status to COMPENSATING and stop normal flow?
stepStatus = runtime_1.NodeStatus.COMPENSATING; // Signal need for compensation
}
return [3 /*break*/, 14];
case 11:
err_1 = _b.sent();
stepStatus = runtime_1.NodeStatus.FAILED;
stepError = err_1 instanceof Error ? err_1 : new index_1.WorkflowError(String(err_1), workflowContext.workflowId);
this.logger.error("Error executing step ".concat(stepConfig.id, ": ").concat(stepError.message), stepError);
return [3 /*break*/, 14];
case 12:
record.status = stepStatus;
record.endTime = new Date();
record.output = stepOutput; // Record step output
record.error = stepError === null || stepError === void 0 ? void 0 : stepError.message;
return [4 /*yield*/, this.emitEvent("step.".concat(stepStatus.toLowerCase()), workflowContext, { stepId: stepConfig.id, type: stepConfig.type, error: stepError === null || stepError === void 0 ? void 0 : stepError.message })];
case 13:
_b.sent();
return [7 /*endfinally*/];
case 14: return [2 /*return*/, { status: stepStatus, nextStepId: nextStepId, output: stepOutput, error: stepError, record: record }];
}
});
});
};
// --- Task Step Execution with Retries/Timeout ---
WorkflowExecutor.prototype.executeTaskStep = function (config, workflowContext) {
return __awaiter(this, void 0, void 0, function () {
var maxRetries, delayMs, timeoutMs, _loop_1, this_1, attempt, state_1;
var _this = this;
var _a, _b, _c, _d;
return __generator(this, function (_e) {
switch (_e.label) {
case 0:
maxRetries = (_b = (_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 0;
delayMs = (_d = (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.delayMs) !== null && _d !== void 0 ? _d : 0;
timeoutMs = config.timeoutMs;
_loop_1 = function (attempt) {
var nodeContext, nodeInfo, executionPromise, nodeOutput, nodeError, nodeStatus, implementation, nodeExecuteFn, nodeInstance, simpleFunc_1, timeoutPromise, err_2;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
nodeContext = (0, context_1.createNodeContext)(workflowContext, config.id, config.nodeId, attempt);
nodeInfo = this_1.nodeRegistry.get(config.nodeId);
if (!nodeInfo) {
throw new index_1.ConfigurationError("Node '".concat(config.nodeId, "' not registered."));
}
// --- Resolve Input Mapping ---
this_1.resolveInputMapping(config, workflowContext, nodeContext);
executionPromise = void 0;
nodeOutput = undefined;
nodeError = undefined;
nodeStatus = runtime_1.NodeStatus.RUNNING;
_f.label = 1;
case 1:
_f.trys.push([1, 10, 13, 14]);
implementation = nodeInfo.implementation;
nodeExecuteFn = void 0;
if (!nodeInfo.isClassInstance) return [3 /*break*/, 4];
nodeInstance = implementation;
// --- Optional: Role Check ---
if (nodeInstance.requiredRoles && !this_1.checkRoles(workflowContext.userRole, nodeInstance.requiredRoles)) {
throw new index_1.AuthorizationError("User role '".concat(workflowContext.userRole, "' not authorized for node '").concat(config.nodeId, "'. Required: ").concat(nodeInstance.requiredRoles.join(', ')));
}
if (!nodeInstance.validate) return [3 /*break*/, 3];
return [4 /*yield*/, nodeInstance.validate(nodeContext)];
case 2:
_f.sent();
_f.label = 3;
case 3:
nodeExecuteFn = nodeInstance.execute.bind(nodeInstance); // Bind context
return [3 /*break*/, 5];
case 4:
simpleFunc_1 = implementation;
// Wrap simple function to match BaseNode execute signature if needed,
// or adjust BaseNode execute signature/context passing.
// For simplicity, assume NodeFunction takes INodeContext now.
nodeExecuteFn = function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, simpleFunc_1(ctx, ctx.input)];
case 1:
result = _a.sent();
if (result !== undefined) {
ctx.output = result; // Assume direct return is output
}
return [2 /*return*/];
}
});
}); };
_f.label = 5;
case 5:
// --- Execute with Timeout ---
executionPromise = nodeExecuteFn(nodeContext);
if (!(timeoutMs && timeoutMs > 0)) return [3 /*break*/, 7];
timeoutPromise = new Promise(function (_, reject) {
return setTimeout(function () { return reject(new index_1.TimeoutError("Node '".concat(config.nodeId, "' timed out after ").concat(timeoutMs, "ms."), config.nodeId, config.id)); }, timeoutMs);
});
return [4 /*yield*/, Promise.race([executionPromise, timeoutPromise])];
case 6:
_f.sent();
return [3 /*break*/, 9];
case 7: return [4 /*yield*/, executionPromise];
case 8:
_f.sent();
_f.label = 9;
case 9:
// --- Execution Success ---
nodeStatus = runtime_1.NodeStatus.COMPLETED;
nodeOutput = nodeContext.output; // Get output potentially set on context
// --- Resolve Output Mapping ---
this_1.resolveOutputMapping(config, nodeContext, workflowContext);
return [2 /*return*/, "break"];
case 10:
err_2 = _f.sent();
// --- Execution Error ---
nodeError = err_2 instanceof Error ? err_2 : new index_1.NodeExecutionError(String(err_2), config.nodeId, config.id);
nodeContext.error = nodeError; // Record error on node context for logging/history
nodeStatus = err_2 instanceof index_1.TimeoutError ? runtime_1.NodeStatus.TIMEOUT : runtime_1.NodeStatus.FAILED;
this_1.logger.warn("Attempt ".concat(attempt + 1, "/").concat(maxRetries + 1, " failed for node ").concat(config.nodeId, " in step ").concat(config.id, ": ").concat(nodeError.message));
if (attempt >= maxRetries) {
this_1.logger.error("Node ".concat(config.nodeId, " failed after ").concat(maxRetries, " retries in step ").concat(config.id, "."), nodeError);
return [2 /*return*/, "break"];
}
if (!(delayMs > 0)) return [3 /*break*/, 12];
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, delayMs); })];
case 11:
_f.sent(); // Wait before retry
_f.label = 12;
case 12: return [3 /*break*/, 14];
case 13:
nodeContext.status = nodeStatus; // Final status for this attempt
nodeContext.endTime = new Date();
// Log node execution attempt details if necessary
this_1.updateHistory(workflowContext, {
stepId: config.id, nodeId: config.nodeId, status: nodeStatus,
startTime: nodeContext.startTime, endTime: nodeContext.endTime,
error: nodeError === null || nodeError === void 0 ? void 0 : nodeError.message, retries: attempt
});
return [7 /*endfinally*/];
case 14: return [2 /*return*/];
}
});
};
this_1 = this;
attempt = 0;
_e.label = 1;
case 1:
if (!(attempt <= maxRetries)) return [3 /*break*/, 4];
return [5 /*yield**/, _loop_1(attempt)];
case 2:
state_1 = _e.sent();
if (state_1 === "break")
return [3 /*break*/, 4];
_e.label = 3;
case 3:
attempt++;
return [3 /*break*/, 1];
case 4: // End retry loop
return [2 /*return*/, { status: runtime_1.NodeStatus.COMPLETED }];
}
});
});
};
// --- Condition Step Execution ---
WorkflowExecutor.prototype.executeConditionStep = function (config, workflowContext) {
return __awaiter(this, void 0, void 0, function () {
var conditionFn, branchKey, nextStepId;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
conditionFn = config.condition;
return [4 /*yield*/, conditionFn(workflowContext)];
case 1:
branchKey = _a.sent();
nextStepId = config.branches[String(branchKey)];
this.logger.info("Condition step '".concat(config.id, "' evaluated to '").concat(branchKey, "'. Next step: ").concat(nextStepId || 'None'));
return [2 /*return*/, { nextStepId: nextStepId, branchKey: branchKey }];
}
});
});
};
// --- Helper Methods ---
WorkflowExecutor.prototype.updateHistory = function (context, record) {
// Ensure history is mutable locally if needed, or handle immutability
context.history.push(record);
// Optional: Limit history size
};
WorkflowExecutor.prototype.resolveInputMapping = function (stepConfig, wfCtx, nodeCtx) {
var resolvedInput = __assign({}, stepConfig.input); // Start with static input
if (stepConfig.inputMapping) {
for (var targetField in stepConfig.inputMapping) {
var sourcePath = stepConfig.inputMapping[targetField];
resolvedInput[targetField] = this.resolveContextPath(sourcePath, wfCtx);
}
}
// Make resolved input available on node context
nodeCtx.input = Object.freeze(resolvedInput); // Make immutable
this.logger.debug("Resolved input for step ".concat(stepConfig.id, ":"), resolvedInput);
};
WorkflowExecutor.prototype.resolveOutputMapping = function (stepConfig, nodeCtx, wfCtx) {
if (stepConfig.outputMapping && nodeCtx.output) {
for (var targetPath in stepConfig.outputMapping) {
var sourceField = stepConfig.outputMapping[targetPath];
var value = nodeCtx.output[sourceField];
this.setContextPath(targetPath, value, wfCtx);
this.logger.debug("Mapped output '".concat(sourceField, "' to '").concat(targetPath, "' for step ").concat(stepConfig.id));
}
}
};
// Resolve value from context using dot notation (e.g., "variables.user.id", "input.orderId", "steps.step1.output.result")
WorkflowExecutor.prototype.resolveContextPath = function (path, context) {
var parts = path.split('.');
var current = context;
if (parts[0] === 'variables') {
current = context.variables;
parts.shift();
}
else if (parts[0] === 'input') {
current = context.input;
parts.shift();
}
else if (parts[0] === 'steps') {
// Access output from previous steps via history? Or a dedicated step output cache?
// Accessing history might be complex. Let's assume direct variable access for now.
// This part needs careful design. For simplicity, only support 'variables' and 'input' for now.
this.logger.warn("Resolving step outputs via path ('".concat(path, "') not fully supported yet. Use variables."));
return undefined;
}
else {
// Assume it's a top-level context property or variable implicitly
current = context.variables; // Default to checking variables
}
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
var part = parts_1[_i];
if (current === null || typeof current !== 'object')
return undefined;
current = current[part];
}
return current;
};
// Set value in context using dot notation (only supports 'variables' for now)
WorkflowExecutor.prototype.setContextPath = function (path, value, context) {
var parts = path.split('.');
if (parts[0] !== 'variables' || parts.length < 2) {
this.logger.error("Output mapping path '".concat(path, "' is invalid. Only 'variables.xxx' is supported."));
return;
}
var current = context.variables;
for (var i = 1; i < parts.length - 1; i++) {
var part = parts[i];
if (current[part] === undefined || typeof current[part] !== 'object') {
current[part] = {}; // Create nested objects if they don't exist
}
current = current[part];
}
current[parts[parts.length - 1]] = value;
};
WorkflowExecutor.prototype.checkRoles = function (userRole, requiredRoles) {
if (!requiredRoles || requiredRoles.length === 0)
return true; // No roles required
if (!userRole)
return false; // Roles required but user has none
// Simple check: user must have at least one of the required roles
// Could be more complex (e.g., all roles required)
return requiredRoles.includes(userRole);
};
// Helper to emit events via the event manager
WorkflowExecutor.prototype.emitEvent = function (eventName, context, payload) {
return __awaiter(this, void 0, void 0, function () {
var err_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.eventManager) return [3 /*break*/, 4];
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this.eventManager.emit(eventName, __assign(__assign({}, (payload || {})), { workflowId: context.workflowId, definitionId: context.definitionId }), context)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
err_3 = _a.sent();
this.logger.error("Failed to emit event '".concat(eventName, "' for workflow ").concat(context.workflowId), err_3);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
};
return WorkflowExecutor;
}());
exports.WorkflowExecutor = WorkflowExecutor;