@5minds/node-red-contrib-processcube 0.14.0-feature-bdf6dc-lyw1t0bw → 0.14.0-feature-084b12-lyxa7tam

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,6 +11,10 @@ services:
11
11
  - FLOWS=/nodered/node-red-contrib-processcube-flows.json
12
12
  volumes:
13
13
  - ./nodered/:/nodered/
14
+ - ./examples/:/examples/
15
+ depends_on:
16
+ - engine
17
+ - authority
14
18
 
15
19
  engine:
16
20
  image: 5minds/processcube_engine:2024-1
@@ -19,9 +23,12 @@ services:
19
23
  volumes:
20
24
  - ./processes:/processes:ro
21
25
  environment:
26
+ application__name: Engine for Node-RED contrib
22
27
  iam__baseUrl: http://authority:11560
23
28
  iam__allowAnonymousRootAccess: true
24
29
  command: --seed-dir=/processes --port 8000
30
+ depends_on:
31
+ - authority
25
32
 
26
33
  authority:
27
34
  image: 5minds/processcube_authority:3.0.4
@@ -10,22 +10,24 @@ module.exports = function(RED) {
10
10
 
11
11
  const externalTaskId = msg.externalTaskId;
12
12
 
13
- let error = msg.error;
13
+ let msgError = msg.error;
14
14
 
15
- if (error === undefined) {
16
- error.message = "An error occurred";
17
- error.source = msg.payload;
15
+ if (msgError === undefined) {
16
+ msgError.message = "An error occurred";
17
+ msgError.source = msg.payload;
18
18
  }
19
19
 
20
- msg.payload = {
21
- "error": {
22
- errorCode: config.error,
23
- errorMessage: error.message,
24
- errorDetails: error.source
25
- }
26
- };
20
+ msg.errorCode = config.error;
21
+ msg.errorMessage = msgError.message;
22
+ msg.errorDetails = msgError.source;
27
23
 
28
- eventEmitter.emit(`handle-${externalTask.flowNodeInstanceId}`, msg, true);
24
+ const error = new Error(msg.errorMessage);
25
+ error.errorCode = msg.errorCode;
26
+ error.errorDetails = msg.errorDetails;
27
+ error.externalTaskId = externalTaskId;
28
+ error._msgid = msg._msgid;
29
+
30
+ eventEmitter.emit(`handle-${externalTaskId}`, error, true);
29
31
 
30
32
  node.send(msg);
31
33
  });
@@ -46,27 +46,35 @@ module.exports = function(RED) {
46
46
  return await new Promise((resolve, reject) => {
47
47
 
48
48
  const handleFinishTask = (msg) => {
49
+ let result = RED.util.encodeObject(msg.payload);
50
+
51
+ node.log(`handle event for external task ${externalTask.flowNodeInstanceId} and process it with result ${result} on msg._msgid ${msg._msgid}.`);
52
+
49
53
  if (msg.externalTaskId) {
50
54
  delete started_external_tasks[msg.externalTaskId];
51
55
  }
52
56
 
53
- showStatus(node, len(started_external_tasks.keys()));
57
+ showStatus(node, Object.keys(started_external_tasks).length);
54
58
 
55
- let result = RED.util.encodeObject(msg.payload);
56
59
 
57
60
  resolve(result);
58
61
  };
59
62
 
60
63
  const handleErrorTask = (msg) => {
64
+
65
+ node.log(`handle error event for external task ${externalTask.flowNodeInstanceId} with result ${msg} on msg._msgid ${msg._msgid}.`);
66
+
61
67
  if (msg.externalTaskId) {
62
68
  delete started_external_tasks[msg.externalTaskId];
63
69
  }
64
70
 
65
- showStatus(node, len(started_external_tasks.keys()));
71
+ showStatus(node, Object.keys(started_external_tasks).length);
66
72
 
67
- let result = RED.util.encodeObject(msg);
68
73
 
69
- reject(result);
74
+ // TODO: with reject, the default error handling is proceed
75
+ // SEE: https://github.com/5minds/ProcessCube.Engine.Client.ts/blob/develop/src/ExternalTaskWorker.ts#L180
76
+ // reject(result);
77
+ resolve(msg);
70
78
  };
71
79
 
72
80
  eventEmitter.once(`handle-${externalTask.flowNodeInstanceId}`, (msg, isError = false) => {
@@ -81,7 +89,7 @@ module.exports = function(RED) {
81
89
 
82
90
  started_external_tasks[externalTask.flowNodeInstanceId] = externalTask;
83
91
 
84
- showStatus(node, len(started_external_tasks.keys()));
92
+ showStatus(node, Object.keys(started_external_tasks).length);
85
93
 
86
94
  let msg = {
87
95
  _msgid: RED.util.generateId(),
@@ -105,19 +113,29 @@ module.exports = function(RED) {
105
113
 
106
114
  // export type WorkerErrorHandler = (errorType: 'fetchAndLock' | 'extendLock' | 'processExternalTask' | 'finishExternalTask', error: Error, externalTask?: ExternalTask<any>) => void;
107
115
  externalTaskWorker.onWorkerError((errorType, error, externalTask) => {
108
- node.error(`Worker error ${errorType} for external task ${externalTask.flowNodeInstanceId}: ${error.message}`);
109
- externalTaskWorker.stop();
116
+ switch (errorType) {
117
+ case 'extendLock':
118
+ case 'finishExternalTask':
119
+ case 'processExternalTask':
120
+ node.error(`Worker error ${errorType} for external task ${externalTask.flowNodeInstanceId}: ${error.message}`);
121
+
122
+ externalTaskWorker.stop();
110
123
 
111
- if (msg.externalTaskId) {
112
- delete started_external_tasks[msg.externalTaskId];
113
- }
124
+ if (externalTask) {
125
+ delete started_external_tasks[externalTask.flowNodeInstanceId];
126
+ }
114
127
 
115
- showStatus(node, len(started_external_tasks.keys()));
128
+ showStatus(node, Object.keys(started_external_tasks).length);
129
+ break;
130
+ default:
131
+ node.error(`Worker error ${errorType}: ${error.message}`);
132
+ break;
133
+ }
116
134
  });
117
135
 
118
- await externalTaskWorker.start();
136
+ externalTaskWorker.start();
119
137
 
120
- node.on("close", async () => {
138
+ node.on("close", () => {
121
139
  try {
122
140
  externalTaskWorker.stop();
123
141
  } catch {
@@ -14,7 +14,7 @@ module.exports = function(RED) {
14
14
  node.error('Error: The message did not contain the required external task id.', msg);
15
15
  }
16
16
 
17
- eventEmitter.emit(`handle-${externalTask.flowNodeInstanceId}`, msg, false);
17
+ eventEmitter.emit(`handle-${externalTaskId}`, msg, false);
18
18
  });
19
19
  }
20
20
  RED.nodes.registerType("externaltask-output", ExternalTaskOutput);
@@ -79,6 +79,61 @@
79
79
  "w": 572,
80
80
  "h": 142
81
81
  },
82
+ {
83
+ "id": "70d7a70e375b162a",
84
+ "type": "group",
85
+ "z": "a23d2e782beb66f4",
86
+ "style": {
87
+ "stroke": "#999999",
88
+ "stroke-opacity": "1",
89
+ "fill": "none",
90
+ "fill-opacity": "1",
91
+ "label": true,
92
+ "label-position": "nw",
93
+ "color": "#a4a4a4"
94
+ },
95
+ "nodes": [
96
+ "2991a5e6df2b87d2",
97
+ "911fde53bcbb7e3f",
98
+ "d56bb7cd73fd220c",
99
+ "75c7bb5cc34e354a",
100
+ "69aec57d8bb00292",
101
+ "15a5f64b9e2e05fc"
102
+ ],
103
+ "x": 34,
104
+ "y": 19,
105
+ "w": 572,
106
+ "h": 222
107
+ },
108
+ {
109
+ "id": "31cb6729aac0ba46",
110
+ "type": "group",
111
+ "z": "a23d2e782beb66f4",
112
+ "style": {
113
+ "stroke": "#999999",
114
+ "stroke-opacity": "1",
115
+ "fill": "none",
116
+ "fill-opacity": "1",
117
+ "label": true,
118
+ "label-position": "nw",
119
+ "color": "#a4a4a4"
120
+ },
121
+ "nodes": [
122
+ "18e05d562d48f32d",
123
+ "49aee03a7885fae8",
124
+ "e4555d9019cd3f47",
125
+ "bd68c4bdc53b8f80",
126
+ "fa1c26d470c38efd",
127
+ "019797b5a0882e7b",
128
+ "fb87f79852b22e4a",
129
+ "1ba1e62c9935255f",
130
+ "b49f226ba865e164"
131
+ ],
132
+ "x": 34,
133
+ "y": 279,
134
+ "w": 872,
135
+ "h": 402
136
+ },
82
137
  {
83
138
  "id": "42e6796dddd9d4db",
84
139
  "type": "processcube-engine-config",
@@ -88,11 +143,12 @@
88
143
  "id": "2991a5e6df2b87d2",
89
144
  "type": "externaltask-input",
90
145
  "z": "a23d2e782beb66f4",
146
+ "g": "70d7a70e375b162a",
91
147
  "name": "Test",
92
148
  "engine": "42e6796dddd9d4db",
93
149
  "topic": "Test",
94
- "x": 90,
95
- "y": 400,
150
+ "x": 110,
151
+ "y": 120,
96
152
  "wires": [
97
153
  [
98
154
  "d56bb7cd73fd220c",
@@ -104,15 +160,17 @@
104
160
  "id": "911fde53bcbb7e3f",
105
161
  "type": "externaltask-output",
106
162
  "z": "a23d2e782beb66f4",
163
+ "g": "70d7a70e375b162a",
107
164
  "name": "Test Ende",
108
- "x": 500,
109
- "y": 400,
165
+ "x": 520,
166
+ "y": 120,
110
167
  "wires": []
111
168
  },
112
169
  {
113
170
  "id": "d56bb7cd73fd220c",
114
171
  "type": "delay",
115
172
  "z": "a23d2e782beb66f4",
173
+ "g": "70d7a70e375b162a",
116
174
  "name": "",
117
175
  "pauseType": "delay",
118
176
  "timeout": "1",
@@ -126,8 +184,8 @@
126
184
  "drop": false,
127
185
  "allowrate": false,
128
186
  "outputs": 1,
129
- "x": 280,
130
- "y": 400,
187
+ "x": 300,
188
+ "y": 120,
131
189
  "wires": [
132
190
  [
133
191
  "911fde53bcbb7e3f",
@@ -139,6 +197,7 @@
139
197
  "id": "75c7bb5cc34e354a",
140
198
  "type": "debug",
141
199
  "z": "a23d2e782beb66f4",
200
+ "g": "70d7a70e375b162a",
142
201
  "name": "debug 1",
143
202
  "active": true,
144
203
  "tosidebar": true,
@@ -147,14 +206,15 @@
147
206
  "complete": "false",
148
207
  "statusVal": "",
149
208
  "statusType": "auto",
150
- "x": 260,
151
- "y": 480,
209
+ "x": 280,
210
+ "y": 200,
152
211
  "wires": []
153
212
  },
154
213
  {
155
214
  "id": "69aec57d8bb00292",
156
215
  "type": "debug",
157
216
  "z": "a23d2e782beb66f4",
217
+ "g": "70d7a70e375b162a",
158
218
  "name": "debug 6",
159
219
  "active": true,
160
220
  "tosidebar": true,
@@ -164,19 +224,20 @@
164
224
  "targetType": "msg",
165
225
  "statusVal": "",
166
226
  "statusType": "auto",
167
- "x": 480,
168
- "y": 480,
227
+ "x": 500,
228
+ "y": 200,
169
229
  "wires": []
170
230
  },
171
231
  {
172
232
  "id": "18e05d562d48f32d",
173
233
  "type": "externaltask-input",
174
234
  "z": "a23d2e782beb66f4",
235
+ "g": "31cb6729aac0ba46",
175
236
  "name": "SampleError",
176
237
  "engine": "42e6796dddd9d4db",
177
238
  "topic": "SampleError",
178
- "x": 110,
179
- "y": 640,
239
+ "x": 130,
240
+ "y": 380,
180
241
  "wires": [
181
242
  [
182
243
  "49aee03a7885fae8"
@@ -187,6 +248,7 @@
187
248
  "id": "49aee03a7885fae8",
188
249
  "type": "delay",
189
250
  "z": "a23d2e782beb66f4",
251
+ "g": "31cb6729aac0ba46",
190
252
  "name": "",
191
253
  "pauseType": "delay",
192
254
  "timeout": "5",
@@ -200,8 +262,8 @@
200
262
  "drop": false,
201
263
  "allowrate": false,
202
264
  "outputs": 1,
203
- "x": 350,
204
- "y": 640,
265
+ "x": 370,
266
+ "y": 380,
205
267
  "wires": [
206
268
  [
207
269
  "bd68c4bdc53b8f80"
@@ -212,11 +274,12 @@
212
274
  "id": "e4555d9019cd3f47",
213
275
  "type": "catch",
214
276
  "z": "a23d2e782beb66f4",
277
+ "g": "31cb6729aac0ba46",
215
278
  "name": "",
216
279
  "scope": null,
217
280
  "uncaught": false,
218
- "x": 360,
219
- "y": 760,
281
+ "x": 380,
282
+ "y": 500,
220
283
  "wires": [
221
284
  [
222
285
  "fa1c26d470c38efd",
@@ -229,6 +292,7 @@
229
292
  "id": "bd68c4bdc53b8f80",
230
293
  "type": "function",
231
294
  "z": "a23d2e782beb66f4",
295
+ "g": "31cb6729aac0ba46",
232
296
  "name": "function 1",
233
297
  "func": "throw Error(\"hello error\");\n\nreturn msg;",
234
298
  "outputs": 1,
@@ -237,8 +301,8 @@
237
301
  "initialize": "",
238
302
  "finalize": "",
239
303
  "libs": [],
240
- "x": 560,
241
- "y": 640,
304
+ "x": 580,
305
+ "y": 380,
242
306
  "wires": [
243
307
  [
244
308
  "1ba1e62c9935255f"
@@ -249,6 +313,7 @@
249
313
  "id": "fa1c26d470c38efd",
250
314
  "type": "debug",
251
315
  "z": "a23d2e782beb66f4",
316
+ "g": "31cb6729aac0ba46",
252
317
  "name": "debug 8",
253
318
  "active": true,
254
319
  "tosidebar": true,
@@ -257,14 +322,15 @@
257
322
  "complete": "false",
258
323
  "statusVal": "",
259
324
  "statusType": "auto",
260
- "x": 620,
261
- "y": 760,
325
+ "x": 640,
326
+ "y": 500,
262
327
  "wires": []
263
328
  },
264
329
  {
265
330
  "id": "019797b5a0882e7b",
266
331
  "type": "debug",
267
332
  "z": "a23d2e782beb66f4",
333
+ "g": "31cb6729aac0ba46",
268
334
  "name": "debug 9",
269
335
  "active": true,
270
336
  "tosidebar": true,
@@ -274,18 +340,19 @@
274
340
  "targetType": "msg",
275
341
  "statusVal": "",
276
342
  "statusType": "auto",
277
- "x": 620,
278
- "y": 820,
343
+ "x": 640,
344
+ "y": 560,
279
345
  "wires": []
280
346
  },
281
347
  {
282
348
  "id": "fb87f79852b22e4a",
283
349
  "type": "externaltask-error",
284
350
  "z": "a23d2e782beb66f4",
351
+ "g": "31cb6729aac0ba46",
285
352
  "name": "Fehler",
286
353
  "error": "MyErrorCode",
287
- "x": 570,
288
- "y": 900,
354
+ "x": 590,
355
+ "y": 640,
289
356
  "wires": [
290
357
  []
291
358
  ]
@@ -294,9 +361,10 @@
294
361
  "id": "1ba1e62c9935255f",
295
362
  "type": "externaltask-output",
296
363
  "z": "a23d2e782beb66f4",
364
+ "g": "31cb6729aac0ba46",
297
365
  "name": "",
298
- "x": 770,
299
- "y": 640,
366
+ "x": 790,
367
+ "y": 380,
300
368
  "wires": []
301
369
  },
302
370
  {
@@ -346,6 +414,28 @@
346
414
  "y": 1200,
347
415
  "wires": []
348
416
  },
417
+ {
418
+ "id": "15a5f64b9e2e05fc",
419
+ "type": "comment",
420
+ "z": "a23d2e782beb66f4",
421
+ "g": "70d7a70e375b162a",
422
+ "name": "Simple External Task handling",
423
+ "info": "",
424
+ "x": 180,
425
+ "y": 60,
426
+ "wires": []
427
+ },
428
+ {
429
+ "id": "b49f226ba865e164",
430
+ "type": "comment",
431
+ "z": "a23d2e782beb66f4",
432
+ "g": "31cb6729aac0ba46",
433
+ "name": "Error handling with external tasks",
434
+ "info": "",
435
+ "x": 190,
436
+ "y": 320,
437
+ "wires": []
438
+ },
349
439
  {
350
440
  "id": "f7a9604a17188737",
351
441
  "type": "usertask-new-listener",
@@ -385,7 +385,7 @@ module.exports = {
385
385
  //tours: false,
386
386
 
387
387
  header: {
388
- title: "Node-RED powered by ProcessCube &copy;",
388
+ title: "Node-RED powered by ProcessCube&copy;",
389
389
  url: "https://processcube.io" // optional url to make the header text/image a link to this url
390
390
 
391
391
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5minds/node-red-contrib-processcube",
3
- "version": "0.14.0-feature-bdf6dc-lyw1t0bw",
3
+ "version": "0.14.0-feature-084b12-lyxa7tam",
4
4
  "license": "MIT",
5
5
  "description": "Node-RED nodes for ProcessCube",
6
6
  "authors": [