snow-flow-test 10.0.1-test.205 → 10.0.1-test.207
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -115,19 +115,62 @@ async function executeFlowPatchMutation(
|
|
|
115
115
|
* The UI calls safeEdit(create: flowId) when opening the editor.
|
|
116
116
|
* This must be called before GraphQL mutations on existing flows.
|
|
117
117
|
*/
|
|
118
|
-
async function acquireFlowEditingLock(client: any, flowId: string): Promise<{ success: boolean; error?: string }> {
|
|
118
|
+
async function acquireFlowEditingLock(client: any, flowId: string): Promise<{ success: boolean; error?: string; debug?: any }> {
|
|
119
|
+
var debug: any = {};
|
|
120
|
+
|
|
121
|
+
// Step 1: Call safeEdit(create) GraphQL mutation (same as UI)
|
|
119
122
|
try {
|
|
120
123
|
var mutation = 'mutation { global { snFlowDesigner { safeEdit(safeEditInput: {create: "' + flowId + '"}) { createResult { canEdit id editingUserDisplayName __typename } __typename } __typename } __typename } }';
|
|
121
124
|
var resp = await client.post('/api/now/graphql', { variables: {}, query: mutation });
|
|
122
125
|
var result = resp.data?.data?.global?.snFlowDesigner?.safeEdit?.createResult;
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
debug.graphql_response = result;
|
|
127
|
+
if (result?.canEdit !== true && result?.canEdit !== 'true') {
|
|
128
|
+
var editingUser = result?.editingUserDisplayName || 'another user';
|
|
129
|
+
return { success: false, error: 'Flow is locked by ' + editingUser, debug };
|
|
130
|
+
}
|
|
131
|
+
debug.graphql_canEdit = true;
|
|
132
|
+
} catch (e: any) {
|
|
133
|
+
debug.graphql_error = e.message;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Step 2: Verify a sys_hub_flow_safe_edit record was actually created
|
|
137
|
+
try {
|
|
138
|
+
var checkResp = await client.get('/api/now/table/sys_hub_flow_safe_edit', {
|
|
139
|
+
params: { sysparm_query: 'document_id=' + flowId, sysparm_fields: 'sys_id,document_id,user', sysparm_limit: 1 }
|
|
140
|
+
});
|
|
141
|
+
var existing = checkResp.data.result?.[0];
|
|
142
|
+
if (existing?.sys_id) {
|
|
143
|
+
debug.safe_edit_record = existing.sys_id;
|
|
144
|
+
return { success: true, debug };
|
|
145
|
+
}
|
|
146
|
+
debug.safe_edit_record = 'not_found_after_graphql';
|
|
147
|
+
} catch (e: any) {
|
|
148
|
+
debug.safe_edit_check_error = e.message;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Step 3: Fallback — create the safe_edit record directly via REST API
|
|
152
|
+
// The GraphQL mutation may return canEdit=true without persisting a record.
|
|
153
|
+
try {
|
|
154
|
+
var createResp = await client.post('/api/now/table/sys_hub_flow_safe_edit', {
|
|
155
|
+
document_id: flowId
|
|
156
|
+
});
|
|
157
|
+
var created = createResp.data.result;
|
|
158
|
+
if (created?.sys_id) {
|
|
159
|
+
debug.rest_created = created.sys_id;
|
|
160
|
+
return { success: true, debug };
|
|
125
161
|
}
|
|
126
|
-
|
|
127
|
-
return { success: false, error: 'Flow is locked by ' + editingUser };
|
|
162
|
+
debug.rest_create_response = created;
|
|
128
163
|
} catch (e: any) {
|
|
129
|
-
|
|
164
|
+
debug.rest_create_error = e.message;
|
|
130
165
|
}
|
|
166
|
+
|
|
167
|
+
// If GraphQL said canEdit=true, trust it even if we couldn't verify/create the record
|
|
168
|
+
if (debug.graphql_canEdit) {
|
|
169
|
+
debug.fallback = 'trusting_graphql_canEdit';
|
|
170
|
+
return { success: true, debug };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { success: false, error: 'Could not acquire editing lock (GraphQL + REST fallback both failed)', debug };
|
|
131
174
|
}
|
|
132
175
|
|
|
133
176
|
/**
|
|
@@ -1158,6 +1201,62 @@ async function addActionViaGraphQL(
|
|
|
1158
1201
|
steps.record_action = recordActionResult.steps;
|
|
1159
1202
|
var hasRecordPills = (recordActionResult.labelCacheUpdates.length + recordActionResult.labelCacheInserts.length) > 0;
|
|
1160
1203
|
|
|
1204
|
+
// ── Rewrite shorthand pills in generic action inputs (e.g. Log "message") ────
|
|
1205
|
+
// Non-record inputs (anything other than record/table_name/values) that contain
|
|
1206
|
+
// {{trigger.current.X}} need rewriting to {{Created or Updated_1.current.X}} + labelCache.
|
|
1207
|
+
var PILL_SHORTHANDS_ACTION = ['trigger.current', 'current', 'trigger_record', 'trigger.record'];
|
|
1208
|
+
var RECORD_INPUTS = ['record', 'table_name', 'values'];
|
|
1209
|
+
var genericPillInputs: { name: string; fields: string[]; isRecordLevel: boolean }[] = [];
|
|
1210
|
+
var actionTriggerInfo: any = null;
|
|
1211
|
+
|
|
1212
|
+
for (var gpi = 0; gpi < recordActionResult.inputs.length; gpi++) {
|
|
1213
|
+
var gpInput = recordActionResult.inputs[gpi];
|
|
1214
|
+
if (RECORD_INPUTS.includes(gpInput.name)) continue;
|
|
1215
|
+
var gpVal = gpInput.value?.value || '';
|
|
1216
|
+
if (!gpVal.includes('{{')) continue;
|
|
1217
|
+
|
|
1218
|
+
var gpHasShorthand = PILL_SHORTHANDS_ACTION.some(function (sh) {
|
|
1219
|
+
return gpVal.includes('{{' + sh + '.') || gpVal.includes('{{' + sh + '}}');
|
|
1220
|
+
});
|
|
1221
|
+
if (!gpHasShorthand) continue;
|
|
1222
|
+
|
|
1223
|
+
// Get trigger info if not already fetched
|
|
1224
|
+
if (!actionTriggerInfo) {
|
|
1225
|
+
actionTriggerInfo = await getFlowTriggerInfo(client, flowId);
|
|
1226
|
+
steps.action_trigger_info = {
|
|
1227
|
+
dataPillBase: actionTriggerInfo.dataPillBase, triggerName: actionTriggerInfo.triggerName,
|
|
1228
|
+
table: actionTriggerInfo.table, tableLabel: actionTriggerInfo.tableLabel
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
if (!actionTriggerInfo.dataPillBase) continue;
|
|
1232
|
+
|
|
1233
|
+
var gpPillBase = actionTriggerInfo.dataPillBase;
|
|
1234
|
+
var gpOrigVal = gpVal;
|
|
1235
|
+
for (var gsi = 0; gsi < PILL_SHORTHANDS_ACTION.length; gsi++) {
|
|
1236
|
+
var gsh = PILL_SHORTHANDS_ACTION[gsi];
|
|
1237
|
+
gpVal = gpVal.split('{{' + gsh + '.').join('{{' + gpPillBase + '.');
|
|
1238
|
+
gpVal = gpVal.split('{{' + gsh + '}}').join('{{' + gpPillBase + '}}');
|
|
1239
|
+
}
|
|
1240
|
+
gpInput.value.value = gpVal;
|
|
1241
|
+
|
|
1242
|
+
// Extract field names from pills for labelCache
|
|
1243
|
+
var gpPillFields: string[] = [];
|
|
1244
|
+
var gpIsRecordLevel = false;
|
|
1245
|
+
var gpPillRx = /\{\{([^}]+)\}\}/g;
|
|
1246
|
+
var gpm: RegExpExecArray | null;
|
|
1247
|
+
while ((gpm = gpPillRx.exec(gpVal)) !== null) {
|
|
1248
|
+
var gpParts = gpm[1].split('.');
|
|
1249
|
+
if (gpParts.length > 2) {
|
|
1250
|
+
gpPillFields.push(gpParts[gpParts.length - 1]);
|
|
1251
|
+
} else {
|
|
1252
|
+
gpIsRecordLevel = true;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
genericPillInputs.push({ name: gpInput.name, fields: gpPillFields, isRecordLevel: gpIsRecordLevel });
|
|
1257
|
+
steps['pill_rewrite_' + gpInput.name] = { original: gpOrigVal, rewritten: gpVal };
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1161
1260
|
// For record actions: clear data pill values from INSERT — they'll be set via separate UPDATE
|
|
1162
1261
|
// (Flow Designer's GraphQL API ignores labelCache during INSERT, it only works with UPDATE)
|
|
1163
1262
|
var insertInputs = recordActionResult.inputs;
|
|
@@ -1270,6 +1369,64 @@ async function addActionViaGraphQL(
|
|
|
1270
1369
|
}
|
|
1271
1370
|
}
|
|
1272
1371
|
|
|
1372
|
+
// Step 3: UPDATE labelCache for generic action inputs with data pills (e.g. Log "message")
|
|
1373
|
+
if (genericPillInputs.length > 0 && actionTriggerInfo?.dataPillBase) {
|
|
1374
|
+
try {
|
|
1375
|
+
var gpLabelInserts: any[] = [];
|
|
1376
|
+
var gpBase = actionTriggerInfo.dataPillBase;
|
|
1377
|
+
var gpTrigName = actionTriggerInfo.triggerName;
|
|
1378
|
+
var gpTable = actionTriggerInfo.tableRef || actionTriggerInfo.table;
|
|
1379
|
+
var gpTableLabel = actionTriggerInfo.tableLabel;
|
|
1380
|
+
|
|
1381
|
+
for (var gli = 0; gli < genericPillInputs.length; gli++) {
|
|
1382
|
+
var gpi2 = genericPillInputs[gli];
|
|
1383
|
+
|
|
1384
|
+
// Field-level pills: build labelCache with metadata from sys_dictionary
|
|
1385
|
+
if (gpi2.fields.length > 0) {
|
|
1386
|
+
var gpFieldEntries = await buildConditionLabelCache(
|
|
1387
|
+
client, '', gpBase, gpTrigName, gpTable, gpTableLabel, uuid, gpi2.fields, gpi2.name
|
|
1388
|
+
);
|
|
1389
|
+
gpLabelInserts = gpLabelInserts.concat(gpFieldEntries);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// Record-level pill
|
|
1393
|
+
if (gpi2.isRecordLevel) {
|
|
1394
|
+
gpLabelInserts.push({
|
|
1395
|
+
name: gpBase,
|
|
1396
|
+
label: 'Trigger - Record ' + gpTrigName + '\u279b' + gpTableLabel + ' Record\u279b' + gpTableLabel,
|
|
1397
|
+
reference: gpTable,
|
|
1398
|
+
reference_display: gpTableLabel,
|
|
1399
|
+
type: 'reference',
|
|
1400
|
+
base_type: 'reference',
|
|
1401
|
+
parent_table_name: gpTable,
|
|
1402
|
+
column_name: '',
|
|
1403
|
+
attributes: '',
|
|
1404
|
+
choices: {},
|
|
1405
|
+
usedInstances: [{ uiUniqueIdentifier: uuid, inputName: gpi2.name }]
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
if (gpLabelInserts.length > 0) {
|
|
1411
|
+
var gpUpdatePatch: any = {
|
|
1412
|
+
flowId: flowId,
|
|
1413
|
+
actions: {
|
|
1414
|
+
update: [{
|
|
1415
|
+
uiUniqueIdentifier: uuid,
|
|
1416
|
+
type: 'action',
|
|
1417
|
+
}]
|
|
1418
|
+
},
|
|
1419
|
+
labelCache: { insert: gpLabelInserts }
|
|
1420
|
+
};
|
|
1421
|
+
steps.generic_pill_label_cache_mutation = jsToGraphQL(gpUpdatePatch);
|
|
1422
|
+
await executeFlowPatchMutation(client, gpUpdatePatch, actionResponseFields);
|
|
1423
|
+
steps.generic_pill_label_cache_update = { success: true, count: gpLabelInserts.length };
|
|
1424
|
+
}
|
|
1425
|
+
} catch (gpe: any) {
|
|
1426
|
+
steps.generic_pill_label_cache_update = { success: false, error: gpe.message };
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1273
1430
|
return { success: true, actionId: actionId || undefined, steps };
|
|
1274
1431
|
} catch (e: any) {
|
|
1275
1432
|
steps.insert = { success: false, error: e.message };
|
|
@@ -1614,7 +1771,8 @@ async function buildConditionLabelCache(
|
|
|
1614
1771
|
table: string,
|
|
1615
1772
|
tableLabel: string,
|
|
1616
1773
|
logicUiId: string,
|
|
1617
|
-
explicitFields?: string[]
|
|
1774
|
+
explicitFields?: string[],
|
|
1775
|
+
inputName?: string
|
|
1618
1776
|
): Promise<any[]> {
|
|
1619
1777
|
if (!dataPillBase) return [];
|
|
1620
1778
|
|
|
@@ -1680,7 +1838,7 @@ async function buildConditionLabelCache(
|
|
|
1680
1838
|
base_type: meta.type,
|
|
1681
1839
|
parent_table_name: table,
|
|
1682
1840
|
column_name: f,
|
|
1683
|
-
usedInstances: [{ uiUniqueIdentifier: logicUiId, inputName: 'condition' }],
|
|
1841
|
+
usedInstances: [{ uiUniqueIdentifier: logicUiId, inputName: inputName || 'condition' }],
|
|
1684
1842
|
choices: {}
|
|
1685
1843
|
});
|
|
1686
1844
|
}
|
|
@@ -2163,6 +2321,60 @@ async function addFlowLogicViaGraphQL(
|
|
|
2163
2321
|
steps.condition_not_encoded_query = true;
|
|
2164
2322
|
}
|
|
2165
2323
|
|
|
2324
|
+
// ── Rewrite shorthand pills in non-condition inputs (e.g. FOR_EACH "items") ────
|
|
2325
|
+
// These inputs may contain {{trigger.current}} or {{current.field}} that need rewriting
|
|
2326
|
+
// to the full dataPillBase (e.g. {{Created or Updated_1.current}}) + labelCache for rendering.
|
|
2327
|
+
var nonConditionPillInputs: { name: string; fields: string[]; isRecordLevel: boolean }[] = [];
|
|
2328
|
+
for (var nci = 0; nci < inputResult.inputs.length; nci++) {
|
|
2329
|
+
var ncInput = inputResult.inputs[nci];
|
|
2330
|
+
if (ncInput.name === 'condition' || ncInput.name === 'condition_name') continue;
|
|
2331
|
+
var ncVal = ncInput.value?.value || '';
|
|
2332
|
+
if (!ncVal.includes('{{')) continue;
|
|
2333
|
+
|
|
2334
|
+
var ncHasShorthand = PILL_SHORTHANDS.some(function (sh) {
|
|
2335
|
+
return ncVal.includes('{{' + sh + '.') || ncVal.includes('{{' + sh + '}}');
|
|
2336
|
+
});
|
|
2337
|
+
if (!ncHasShorthand) continue;
|
|
2338
|
+
|
|
2339
|
+
// Get trigger info if not already fetched
|
|
2340
|
+
if (!conditionTriggerInfo) {
|
|
2341
|
+
conditionTriggerInfo = await getFlowTriggerInfo(client, flowId);
|
|
2342
|
+
steps.trigger_info = {
|
|
2343
|
+
dataPillBase: conditionTriggerInfo.dataPillBase, triggerName: conditionTriggerInfo.triggerName,
|
|
2344
|
+
table: conditionTriggerInfo.table, tableLabel: conditionTriggerInfo.tableLabel, error: conditionTriggerInfo.error,
|
|
2345
|
+
debug: conditionTriggerInfo.debug
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
if (!conditionTriggerInfo.dataPillBase) continue;
|
|
2349
|
+
|
|
2350
|
+
var ncPillBase = conditionTriggerInfo.dataPillBase;
|
|
2351
|
+
var ncOrigVal = ncVal;
|
|
2352
|
+
for (var si2 = 0; si2 < PILL_SHORTHANDS.length; si2++) {
|
|
2353
|
+
var sh2 = PILL_SHORTHANDS[si2];
|
|
2354
|
+
ncVal = ncVal.split('{{' + sh2 + '.').join('{{' + ncPillBase + '.');
|
|
2355
|
+
ncVal = ncVal.split('{{' + sh2 + '}}').join('{{' + ncPillBase + '}}');
|
|
2356
|
+
}
|
|
2357
|
+
ncInput.value.value = ncVal;
|
|
2358
|
+
|
|
2359
|
+
// Extract field names from pills for labelCache
|
|
2360
|
+
var ncPillFields: string[] = [];
|
|
2361
|
+
var ncIsRecordLevel = false;
|
|
2362
|
+
var ncPillRx = /\{\{([^}]+)\}\}/g;
|
|
2363
|
+
var ncm: RegExpExecArray | null;
|
|
2364
|
+
while ((ncm = ncPillRx.exec(ncVal)) !== null) {
|
|
2365
|
+
var ncParts = ncm[1].split('.');
|
|
2366
|
+
if (ncParts.length > 2) {
|
|
2367
|
+
ncPillFields.push(ncParts[ncParts.length - 1]);
|
|
2368
|
+
} else {
|
|
2369
|
+
// Record-level pill like {{Created or Updated_1.current}}
|
|
2370
|
+
ncIsRecordLevel = true;
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
nonConditionPillInputs.push({ name: ncInput.name, fields: ncPillFields, isRecordLevel: ncIsRecordLevel });
|
|
2375
|
+
steps['pill_rewrite_' + ncInput.name] = { original: ncOrigVal, rewritten: ncVal };
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2166
2378
|
// Calculate insertion order
|
|
2167
2379
|
const resolvedOrder = await calculateInsertOrder(client, flowId, parentUiId, order);
|
|
2168
2380
|
steps.insert_order = resolvedOrder;
|
|
@@ -2282,6 +2494,65 @@ async function addFlowLogicViaGraphQL(
|
|
|
2282
2494
|
}
|
|
2283
2495
|
}
|
|
2284
2496
|
|
|
2497
|
+
// Step 3: UPDATE labelCache for non-condition inputs with data pills (e.g. FOR_EACH "items")
|
|
2498
|
+
if (nonConditionPillInputs.length > 0 && conditionTriggerInfo?.dataPillBase) {
|
|
2499
|
+
try {
|
|
2500
|
+
var ncLabelInserts: any[] = [];
|
|
2501
|
+
var dPillBase = conditionTriggerInfo.dataPillBase;
|
|
2502
|
+
var dTriggerName = conditionTriggerInfo.triggerName;
|
|
2503
|
+
var dTable = conditionTriggerInfo.tableRef;
|
|
2504
|
+
var dTableLabel = conditionTriggerInfo.tableLabel;
|
|
2505
|
+
|
|
2506
|
+
for (var nli = 0; nli < nonConditionPillInputs.length; nli++) {
|
|
2507
|
+
var ncpi = nonConditionPillInputs[nli];
|
|
2508
|
+
|
|
2509
|
+
// Field-level pills: reuse buildConditionLabelCache with the correct inputName
|
|
2510
|
+
if (ncpi.fields.length > 0) {
|
|
2511
|
+
var ncFieldEntries = await buildConditionLabelCache(
|
|
2512
|
+
client, '', dPillBase, dTriggerName, dTable, dTableLabel, returnedUuid, ncpi.fields, ncpi.name
|
|
2513
|
+
);
|
|
2514
|
+
ncLabelInserts = ncLabelInserts.concat(ncFieldEntries);
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
// Record-level pill (e.g. {{Created or Updated_1.current}}) — add record-level labelCache entry
|
|
2518
|
+
if (ncpi.isRecordLevel) {
|
|
2519
|
+
ncLabelInserts.push({
|
|
2520
|
+
name: dPillBase,
|
|
2521
|
+
label: 'Trigger - Record ' + dTriggerName + '\u279b' + dTableLabel + ' Record\u279b' + dTableLabel,
|
|
2522
|
+
reference: dTable,
|
|
2523
|
+
reference_display: dTableLabel,
|
|
2524
|
+
type: 'reference',
|
|
2525
|
+
base_type: 'reference',
|
|
2526
|
+
parent_table_name: dTable,
|
|
2527
|
+
column_name: '',
|
|
2528
|
+
attributes: '',
|
|
2529
|
+
choices: {},
|
|
2530
|
+
usedInstances: [{ uiUniqueIdentifier: returnedUuid, inputName: ncpi.name }]
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
if (ncLabelInserts.length > 0) {
|
|
2536
|
+
var ncUpdatePatch: any = {
|
|
2537
|
+
flowId: flowId,
|
|
2538
|
+
flowLogics: {
|
|
2539
|
+
update: [{
|
|
2540
|
+
uiUniqueIdentifier: returnedUuid,
|
|
2541
|
+
type: 'flowlogic',
|
|
2542
|
+
}]
|
|
2543
|
+
},
|
|
2544
|
+
labelCache: { insert: ncLabelInserts }
|
|
2545
|
+
};
|
|
2546
|
+
steps.nc_pill_label_cache_mutation = jsToGraphQL(ncUpdatePatch);
|
|
2547
|
+
await executeFlowPatchMutation(client, ncUpdatePatch, logicResponseFields);
|
|
2548
|
+
steps.nc_pill_label_cache_update = { success: true, count: ncLabelInserts.length };
|
|
2549
|
+
}
|
|
2550
|
+
} catch (nce: any) {
|
|
2551
|
+
steps.nc_pill_label_cache_update = { success: false, error: nce.message };
|
|
2552
|
+
// Non-fatal: element was created, just label rendering may be affected
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2285
2556
|
return { success: true, logicId, uiUniqueIdentifier: returnedUuid, steps };
|
|
2286
2557
|
} catch (e: any) {
|
|
2287
2558
|
steps.insert = { success: false, error: e.message };
|
|
@@ -3781,15 +4052,15 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
3781
4052
|
await client.get('/api/now/processflow/flow/' + openFlowId);
|
|
3782
4053
|
} catch (_) { /* best-effort — flow data load is not critical for lock acquisition */ }
|
|
3783
4054
|
|
|
3784
|
-
// Step 2: Acquire editing lock via safeEdit create mutation
|
|
4055
|
+
// Step 2: Acquire editing lock via safeEdit create mutation + REST fallback
|
|
3785
4056
|
var lockResult = await acquireFlowEditingLock(client, openFlowId);
|
|
3786
4057
|
if (lockResult.success) {
|
|
3787
4058
|
openSummary.success('Flow opened for editing (lock acquired)').field('Flow', openFlowId)
|
|
3788
4059
|
.line('You can now use add_action, add_flow_logic, etc. Call close_flow when done.');
|
|
3789
|
-
return createSuccessResult({ action: 'open_flow', flow_id: openFlowId, editing_session: true }, {}, openSummary.build());
|
|
4060
|
+
return createSuccessResult({ action: 'open_flow', flow_id: openFlowId, editing_session: true, lock_debug: lockResult.debug }, {}, openSummary.build());
|
|
3790
4061
|
} else {
|
|
3791
4062
|
openSummary.error('Cannot open flow: ' + (lockResult.error || 'lock acquisition failed')).field('Flow', openFlowId);
|
|
3792
|
-
return createErrorResult('Cannot open flow for editing: ' + (lockResult.error || 'lock acquisition failed'));
|
|
4063
|
+
return createErrorResult('Cannot open flow for editing: ' + (lockResult.error || 'lock acquisition failed') + (lockResult.debug ? ' | debug: ' + JSON.stringify(lockResult.debug) : ''));
|
|
3793
4064
|
}
|
|
3794
4065
|
}
|
|
3795
4066
|
|