node-red-contrib-teamogy-api 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -31,8 +31,15 @@ You must configure a Connection before using this node.
31
31
  | Limit | number | Optional | Limitation of the total number of records in the response (if not specified, the value 0 is used, the value 0 means no limit) |
32
32
  | Paging | number | Optional | Division of responses into multiple parts with the number of records returned (if not specified, the value 1000 is used) |
33
33
  | Offset | number | Optional | Determining from which records to return, e.g. if you have a total of 100 records and want to return records 50-100, set Offset to 50, if you want to return all records leave the option at 0 (if not specified, the value 0 is used) |
34
+ | Delay | number | Optional | Specifies the delay between requests, which is used for pagination (if not specified, the value 0 is used) |
35
+ | Req. repeat | number | Optional | Specifies the number of errors after which the request will be repeated (if not specified, the value 5 is used) |
36
+ | Req. delay (s) | number | Optional | Specifies the delay between requests, which is used when retrying a request in case of an error (if not specified, the value 30 is used) |
34
37
  | Skip | boolean | Optional, in message only | Adding the msg.skip=true will allow the message to pass through to the output without processing |
35
-
38
+ | Connection | string | Optional, in message only | Replaces connection from configuration, use connection name |
39
+ | Unit | number | Optional, in message only | Replaces unit from connection configuration, use unit/agency id |
40
+ | Entity | string | Optional, in message only | Replaces entity from configuration, use v_entityName for views or r_entityName |
41
+ | Method | string | Optional, in message only | Replaces method from configuration, use the available method for the given entity |
42
+
36
43
  ## Examples
37
44
 
38
45
  ### Static Request Examples
@@ -89,8 +96,9 @@ msg.body.address = addresses // array of objects
89
96
 
90
97
  | Property | Type | Description |
91
98
  |----------|------|-------------|
92
- | payload | string \| object | The standard output or error of the response |
99
+ | payload | string \| object | The standard output of the response |
93
100
  | count | number | Number of records in the output |
101
+ | error | string | Error message |
94
102
  | msg.* | string \| object | All properties of the input message |
95
103
 
96
104
  ## References
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "node-red-contrib-teamogy-api",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
7
7
  },
8
+ "engines": {
9
+ "node": ">=18.0.0"
10
+ },
8
11
  "keywords": [
9
12
  "node-red",
10
13
  "teamogy",
@@ -17,11 +20,9 @@
17
20
  "author": "",
18
21
  "license": "",
19
22
  "node-red": {
23
+ "version": ">=4.0.0",
20
24
  "nodes": {
21
25
  "teamogy-client": "teamogy-client.js"
22
26
  }
23
- },
24
- "dependencies": {
25
- "node-fetch": "^3.3.2"
26
27
  }
27
28
  }
@@ -73,7 +73,7 @@
73
73
 
74
74
  <div class="form-row">
75
75
  <label for="node-config-input-unit"><i class="fa fa-square-o"></i> <span>Unit/Agency</span></label>
76
- <input type="number" id="node-config-input-unit" min="1" max="100" step="1" placeholder="1" style="width: 20%">
76
+ <input type="number" id="node-config-input-unit" min="0" max="100" step="1" placeholder="1" style="width: 20%">
77
77
  </div>
78
78
 
79
79
  <div class="form-row">
@@ -167,7 +167,7 @@ RED.nodes.registerType('teamogy-config', {
167
167
 
168
168
  $('#node-config-input-unit').on('change', function() {
169
169
  if(!$.isNumeric($(this).val())) { $(this).val(1) } else {
170
- if($(this).val() < 1 || $(this).val() > 100 ) { $(this).val(1) }
170
+ if($(this).val() < 0 || $(this).val() > 100 ) { $(this).val(1) }
171
171
  }
172
172
  })
173
173
 
@@ -220,7 +220,7 @@ RED.nodes.registerType('teamogy-config', {
220
220
  </div>
221
221
 
222
222
  <div class="form-row">
223
- <label for="node-input-mode" style="width: 130px"><i class="fa fa-globe"></i> <span>Request views</span></label>
223
+ <label for="node-input-mode" style="width: 130px"><i class="fa fa-refresh"></i> <span>Request views</span></label>
224
224
  <input type="checkbox" id="node-input-mode" style=" width:20px;">
225
225
  </div>
226
226
 
@@ -260,8 +260,9 @@ RED.nodes.registerType('teamogy-config', {
260
260
  </div>
261
261
 
262
262
  <div class="form-row" id="node-row-response-option">
263
- <label style="width: 130px"><span>Response option</span></label>
264
263
  <div style="margin-bottom: 10px;"></div>
264
+ <label style="width: 130px"></i><span>View option</span></label>
265
+ <div style="margin-bottom: 5px;"></div>
265
266
  <div class="form-row">
266
267
  <label for="node-input-merge" style="width: 130px"><i class="fa fa-compress"></i> <span> Merge</span></label>
267
268
  <input type="checkbox" id="node-input-merge" style=" width:20px;">
@@ -278,6 +279,10 @@ RED.nodes.registerType('teamogy-config', {
278
279
  <label for="node-input-offset" style="width: 130px"><i class="fa fa-forward"></i><span> Offset</span></label>
279
280
  <input type="number" id="node-input-offset" min="0" step="1" style="width:20%">
280
281
  </div>
282
+ <div class="form-row">
283
+ <label for="node-input-delay" style="width: 130px"><i class="fa fa-clock-o"></i><span> Pag. delay (s)</span></label>
284
+ <input type="number" id="node-input-delay" min="0" max="600" step="1" style="width:20%">
285
+ </div>
281
286
  </div>
282
287
 
283
288
  <div class="form-row" id="node-row-editor-dynamic">
@@ -285,8 +290,23 @@ RED.nodes.registerType('teamogy-config', {
285
290
  <label for="node-input-params" style="width: 130px"><i class="fa fa-code"></i> Source of body</label>
286
291
  <input type="text" id="node-input-body-source" style="width: 65%">
287
292
  <input type="hidden" id="node-input-body-source-type" style="width: 0px">
288
- </div>
293
+ </div>
294
+ </div>
295
+
296
+ <div class="form-row" id="node-row-error-option">
297
+ <div style="margin-bottom: 10px;"></div>
298
+ <label style="width: 130px"><span>If an error occurs</span></label>
299
+ <div style="margin-bottom: 5px;"></div>
300
+ <div class="form-row">
301
+ <label for="node-input-repeat" style="width: 130px"><i class="fa fa-repeat"></i><span> Req. repeat</span></label>
302
+ <input type="number" id="node-input-repeat" min="0" max="10" step="1" style="width:20%">
303
+ </div>
304
+ <div class="form-row">
305
+ <label for="node-input-rdelay" style="width: 130px"><i class="fa fa-clock-o"></i><span> Req. delay (s)</span></label>
306
+ <input type="number" id="node-input-rdelay" min="0" max="600" step="1" style="width:20%">
307
+ </div>
289
308
  </div>
309
+
290
310
  </div>
291
311
  </div>
292
312
  </script>
@@ -338,7 +358,19 @@ RED.nodes.registerType('teamogy-client',{
338
358
  offset: {
339
359
  value: 0,
340
360
  required: true
341
- }
361
+ },
362
+ delay: {
363
+ value: 0,
364
+ required: true
365
+ },
366
+ repeat: {
367
+ value: 5,
368
+ required: true
369
+ },
370
+ rdelay: {
371
+ value: 30,
372
+ required: true
373
+ }
342
374
  },
343
375
  inputs: 1,
344
376
  outputs:1,
@@ -367,6 +399,9 @@ RED.nodes.registerType('teamogy-client',{
367
399
  $('#node-input-limit').val(this.limit);
368
400
  $('#node-input-paging').val(this.paging);
369
401
  $('#node-input-offset').val(this.offset);
402
+ $('#node-input-delay').val(this.delay);
403
+ $('#node-input-repeat').val(this.repeat);
404
+ $('#node-input-rdelay').val(this.rdelay);
370
405
 
371
406
  $('#node-input-mode').val(this.mode);
372
407
  $('#node-input-body-source').val(this.bodysource);
@@ -460,6 +495,17 @@ RED.nodes.registerType('teamogy-client',{
460
495
  if(!$.isNumeric($(this).val())) { $(this).val(0) }
461
496
  })
462
497
 
498
+ $('#node-input-delay').on('change', function() {
499
+ if(!$.isNumeric($(this).val())) { $(this).val(0) }
500
+ })
501
+ $('#node-input-repeat').on('change', function() {
502
+ if(!$.isNumeric($(this).val())) { $(this).val(5) }
503
+ })
504
+
505
+ $('#node-input-rdelay').on('change', function() {
506
+ if(!$.isNumeric($(this).val())) { $(this).val(30) }
507
+ })
508
+
463
509
  this.editorp = RED.editor.createEditor({
464
510
  id: 'node-input-params',
465
511
  mode: 'ace/mode/text',
@@ -496,7 +542,11 @@ RED.nodes.registerType('teamogy-client',{
496
542
  if(!$("#node-input-limit").val()) {this.limit = 0} else {this.limit = $("#node-input-limit").val();}
497
543
  if(!$("#node-input-offset").val()) {this.offset = 0} else {this.offset = $("#node-input-offset").val();}
498
544
  this.paging = $("#node-input-paging").val();
499
-
545
+
546
+ if(!$("#node-input-delay").val()) {this.delay = 0} else {this.delay = $("#node-input-delay").val();}
547
+ if(!$("#node-input-repeat").val()) {this.repeat = 0} else {this.repeat = $("#node-input-repeat").val();}
548
+ if(!$("#node-input-rdelay").val()) {this.rdelay = 0} else {this.rdelay = $("#node-input-rdelay").val();}
549
+
500
550
  this.cparams = this.editorp.getValue();
501
551
  this.editorp.destroy();
502
552
  delete this.editorp;
@@ -574,17 +624,25 @@ RED.nodes.registerType('teamogy-client',{
574
624
  <dd> msg.body.address = addresses // array of objects</dd>
575
625
  <dd>&nbsp;</dd>
576
626
  <dd> If you use requests for API views you can use additional options, the options can also be used in dynamic requests</dd>
577
- <dt class="optional">Merge (optional)<span class="property-type">checkbox - yes/no</span></dt><dd> check if you want the output message to contain all returned records. In the background, processing is still taking place according to the Paging settings, but individual messages are not sent to the output, but only the final merged one containing all the returned records. (if not specified the value no is used)</dd>
578
- <dt class="optional">Limit (optional)<span class="property-type">number</span></dt><dd> limitation of the total number of records in the response (if not specified, the value 0 is used, the value 0 means no limit)</dd>
579
- <dt class="optional">Paging (optional)<span class="property-type">number</span></dt><dd> division of responses into multiple parts with the number of records returned (if not specified, the value 1000 is used)</dd>
580
- <dt class="optional">Offset (optional)<span class="property-type">number</span></dt><dd> determining from which records to return, e.g. if you have a total of 100 records and want to return records 50-100, set Offset to 50, if you want to return all records leave the option at 0 (if not specified, the value 0 is used)</dd>
581
- <dt class="optional">Skip (optional, in message only)<span class="property-type">boolean</span></dt><dd> adding the msg.skip=true will allow the message to pass through to the output without processing</dd>
582
- </dl>
627
+ <dt class="optional">Merge (optional) (also in msg.merge (boolean))<span class="property-type">checkbox - yes/no</span></dt><dd> check if you want the output message to contain all returned records. In the background, processing is still taking place according to the Paging settings, but individual messages are not sent to the output, but only the final merged one containing all the returned records. (if not specified the value no is used)</dd>
628
+ <dt class="optional">Limit (optional) (also in msg.limit)<span class="property-type">number</span></dt><dd> limitation of the total number of records in the response (if not specified, the value 0 is used, the value 0 means no limit)</dd>
629
+ <dt class="optional">Paging (optional) (also in msg.paging)<span class="property-type">number</span></dt><dd> division of responses into multiple parts with the number of records returned (if not specified, the value 1000 is used)</dd>
630
+ <dt class="optional">Offset (optional) (also in msg.offset)<span class="property-type">number</span></dt><dd> specifies from which record to start returning data. For example, if you have 100 records total and want to return records 50-100, set Offset to 50. To return all records from the beginning, leave it at 0 (if not specified, the value 0 is used))</dd>
631
+ <dt class="optional">Delay (optional) (also in msg.delay)<span class="property-type">number</span></dt><dd> specifies the delay between requests, which is used for pagination (if not specified, the value 0 is used)</dd>
632
+ <dt class="optional">Req. repeat (optional) (also in msg.repeat)<span class="property-type">number</span></dt><dd> specifies the number of errors after which the request will be repeated (if not specified, the value 5 is used)</dd>
633
+ <dt class="optional">Req. delay (s) (optional) (also in msg.rdelay)<span class="property-type">number</span></dt><dd> specifies the delay between requests, which is used when retrying a request in case of an error (if not specified, the value 30 is used)</dd>
634
+ <dt class="optional">Skip (optional in message only, msg.skip)<span class="property-type">boolean</span></dt><dd> adding the msg.skip=true will allow the message to pass through to the output without processing</dd>
635
+ <dt class="optional">Connection (optional in message, msg.connection)<span class="property-type">string</span></dt><dd> replaces connection from configuration, use connection name</dd>
636
+ <dt class="optional">Unit (optional in message, msg.unit)<span class="property-type">number</span></dt><dd> replaces unit from connection configuration, use unit/agency id</dd>
637
+ <dt class="optional">Entity (optional in message, msg.entity)<span class="property-type">string</span></dt><dd> replaces entity from configuration, use v_entityName for views or r_entityName</dd>
638
+ <dt class="optional">Method (optional in message, msg.method)<span class="property-type">string</span></dt><dd> replaces method from configuration, use the available method for the given entity</dd>
639
+ </dl>
583
640
 
584
641
  <h3>Output</h3>
585
642
  <dl class="message-properties">
586
- <dt>payload<span class="property-type">string | object</span></dt><dd> the standard output or error of the response</dd>
643
+ <dt>payload<span class="property-type">string | object</span></dt><dd> the standard output of the response</dd>
587
644
  <dt>count<span class="property-type">number</span></dt><dd> number of records in the output</dd>
645
+ <dt>error<span class="property-type">string</span></dt><dd> error message</dd>
588
646
  <dt>msg.*<span class="property-type">string | object</span></dt><dd> all properties of the input message</dd>
589
647
  </dl>
590
648
 
package/teamogy-client.js CHANGED
@@ -1,7 +1,49 @@
1
1
  function isEmpty(value) { return (value == null || (typeof value === "string" && value.trim().length === 0)); }
2
2
 
3
+ async function fetchWithRetry(url, options, retries, delay, node) {
4
+ for (let i = 0; i <= retries; i++) {
5
+ try {
6
+ const response = await fetch(url, options);
7
+ if (response.status >= 200 && response.status < 300) {
8
+ return response;
9
+ }
10
+
11
+ let o = {}
12
+ o.status = response.status;
13
+ o.message = await response.text();
14
+ o.attempt = i + 1;
15
+ o.delay = delay / 1000;
16
+
17
+ await new Promise(resolve => setTimeout(resolve, delay));
18
+
19
+ } catch (error) {
20
+
21
+ let o = {}
22
+ o.status = 0;
23
+ o.message = 'Request failed';
24
+ o.attempt = i + 1;
25
+ o.delay = delay / 1000;
26
+
27
+ await new Promise(resolve => setTimeout(resolve, delay));
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+
3
33
  module.exports = function(RED) {
4
34
 
35
+ function getConfigId(name) {
36
+ var configNodes = [];
37
+ RED.nodes.eachNode(function(node) {
38
+ if (node.type === "teamogy-config") {
39
+ configNodes.push(node);
40
+ }
41
+ });
42
+
43
+ const configId = configNodes.find(item => item.name === name)?.id;
44
+ return configId;
45
+ }
46
+
5
47
  function ConnectionNode(n) {
6
48
  try {
7
49
  RED.nodes.createNode(this, n);
@@ -42,6 +84,7 @@ module.exports = function(RED) {
42
84
  let token = this.config.credentials.token
43
85
  let host = this.config.host.replace(/^https?:\/\//, '').split('/')[0];
44
86
  let unit = this.config.unit
87
+ let connName = this.config.name
45
88
 
46
89
  let clientid = data.id
47
90
  let c = this.context().global.get('cache_' + host)
@@ -56,7 +99,12 @@ module.exports = function(RED) {
56
99
  let mlimit = 0
57
100
  let mpaging = 1000
58
101
  let moffset = 0
59
-
102
+ let entity = ''
103
+ let method = 'GET'
104
+ let delay = 0;
105
+ let repeat = 5;
106
+ let rdelay = 30;
107
+
60
108
  if(data.source=='dynamic') {
61
109
  if(typeof msg.params == 'string') { mparams = msg.params }
62
110
  if(typeof msg.params == 'object') {
@@ -74,11 +122,30 @@ module.exports = function(RED) {
74
122
  if(typeof msg[data.bodysource] == 'string') { body = msg[data.bodysource] }
75
123
  if(typeof msg[data.bodysource] == 'object') { body = JSON.stringify(msg[data.bodysource]) }
76
124
 
77
- if(typeof msg.merge == 'boolean') { mmerge = msg.merge }
78
- if(typeof msg.limit == 'number') { mlimit = msg.limit }
79
- if(typeof msg.paging == 'number') { mpaging = msg.paging }
80
- if(typeof msg.offset == 'number') { moffset = msg.offset }
125
+ if(typeof msg.merge == 'boolean') { mmerge = msg.merge }
126
+ if(typeof msg.limit == 'number') { mlimit = msg.limit }
127
+ if(typeof msg.paging == 'number') { mpaging = msg.paging }
128
+ if(typeof msg.offset == 'number') { moffset = msg.offset }
129
+ if(typeof msg.unit == 'number') { unit = msg.unit }
130
+ if(typeof msg.entity == 'string') { entity = msg.entity } else { entity = data.entity }
131
+ if(typeof msg.method == 'string') { method = msg.method } else { method = data.method }
132
+ if(typeof msg.delay == 'number') { delay = msg.delay * 1000 } else { delay = data.delay * 1000 }
133
+ if(typeof msg.repeat == 'number') { repeat = msg.repeat ?? 5 } else { repeat = data.repeat ?? 5 }
134
+ if(typeof msg.rdelay == 'number') { rdelay = msg.rdelay * 1000 } else { rdelay = data.rdelay * 1000 }
81
135
 
136
+ if(typeof msg.connection == 'string') {
137
+ if(msg.connection) {
138
+ const customConfig = RED.nodes.getNode(getConfigId(msg.connection));
139
+ if(customConfig) {
140
+ token = customConfig.credentials.token;
141
+ host = customConfig.host.replace(/^https?:\/\//, '').split('/')[0];
142
+ unit = customConfig.unit;
143
+ } else {
144
+ node.warn("Specified connection not found: " + msg.connection + ", using default: " + connName);
145
+ }
146
+ }
147
+ }
148
+
82
149
  }
83
150
 
84
151
  if(data.source=='static') {
@@ -95,40 +162,44 @@ module.exports = function(RED) {
95
162
  mlimit = data.limit
96
163
  mpaging = data.paging
97
164
  moffset = data.offset
165
+ entity = data.entity
166
+ method = data.method
167
+ delay = data.delay * 1000
168
+ repeat = data.repeat ?? 5
169
+ rdelay = data.rdelay * 1000
98
170
  }
99
-
171
+
100
172
  const headers = {
101
173
  'Authorization': 'Bearer ' + token,
102
174
  'Accept': 'application/json',
103
175
  'Content-type': 'application/json'
104
176
  };
105
-
177
+
106
178
  let url = `https://${host}/rest/v1/${unit}/`
107
179
 
108
- if(data.entity.split('_')[0] == 'v') { url = url + 'views/'}
180
+ if(entity.split('_')[0] == 'v') { url = url + 'views/'}
109
181
 
110
- url = url + data.entity.split('_')[1].replaceAll('-','.')
182
+ url = url + entity.split('_')[1].replaceAll('-','.')
111
183
 
112
184
  if(!isEmpty(mparams)) { url = url + '?' + mparams }
113
-
185
+
114
186
  const doAsyncJobs = async () => {
115
187
  try {
116
188
 
117
- let newMsg = JSON.parse(JSON.stringify(mesg.msg));
118
-
119
189
  let metadata = {};
120
190
  metadata.count = 0
121
191
  metadata.limit = 0
122
192
  let rdata = [];
123
-
124
- let method = data.method
193
+
125
194
  let offset = moffset
126
-
195
+
127
196
  if(method == 'GET') { body = null }
128
197
 
129
- if(data.entity.split('_')[0] == 'v') {
198
+ if(entity.split('_')[0] == 'v') {
130
199
  if(isEmpty(mparams)) { url = url + '?' } else { url = url + '&' }
131
200
 
201
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
202
+
132
203
  while (offset != null) {
133
204
 
134
205
  if(parseInt(mlimit) == 0) { mlimit = 1000000000}
@@ -136,9 +207,9 @@ module.exports = function(RED) {
136
207
 
137
208
  eurl = encodeURI(url + 'limit=' + mpaging +'&offset=' + offset)
138
209
 
139
- const response = await fetch(eurl, {headers, method, body});
210
+ const response = await fetchWithRetry(eurl, { headers, method, body }, repeat, rdelay, node);
140
211
 
141
- if(response.status >= 200 && response.status < 300) {
212
+ if(response && response.status >= 200 && response.status < 300) {
142
213
 
143
214
  const body = await response.json();
144
215
  offset = body?.metadata?.nextOffset
@@ -149,9 +220,9 @@ module.exports = function(RED) {
149
220
  if(mlimit - metadata.count < mpaging) { mpaging = mlimit - metadata.count}
150
221
 
151
222
  if(mmerge == false) {
152
- newMsg.payload=body;
153
- newMsg.payload.count=body.data.length;
154
- node.send(JSON.parse(JSON.stringify(newMsg)));
223
+ msg.payload = body;
224
+ msg.count = body.data.length;
225
+ node.send(msg);
155
226
  }
156
227
 
157
228
  if(mmerge == true) {
@@ -161,10 +232,22 @@ module.exports = function(RED) {
161
232
  }
162
233
 
163
234
  if(mlimit <= metadata.count) { break; }
164
-
235
+ if (offset != null && delay > 0) { await sleep(delay); }
236
+
165
237
  } else {
166
- node.error('Response status: ' + response.status);
167
- node.error('Response status: ' + await response.text());
238
+ if (!response) {
239
+ node.error('Request failed after all attempts.');
240
+ msg.error = 'Request failed after all attempts.'
241
+ msg.payload = null;
242
+ if(msg.res){
243
+ msg.payload = JSON.stringify('Request failed after all attempts.');
244
+ msg.statusCode = 500;
245
+ }
246
+ node.send(msg);
247
+ } else {
248
+ node.error('Response status: ' + response.status);
249
+ node.error('Response text: ' + await response.text());
250
+ }
168
251
  break;
169
252
  }
170
253
  }
@@ -174,27 +257,34 @@ module.exports = function(RED) {
174
257
  metadata.limit = parseInt(data.paging)
175
258
  body.metadata = metadata
176
259
  body.data = rdata
177
- body.count = rdata.length
178
- newMsg.payload = body
179
- node.send(JSON.parse(JSON.stringify(newMsg)));
260
+ msg.payload = body
261
+ msg.count = rdata.length
262
+ node.send(msg);
180
263
  }
181
264
  }
182
265
 
183
- if(data.entity.split('_')[0] == 'r') {
266
+ if(entity.split('_')[0] == 'r') {
184
267
 
185
- const response = await fetch(encodeURI(url), {headers, method, body});
268
+ const response = await fetchWithRetry(encodeURI(url), { headers, method, body }, repeat, rdelay, node);
186
269
 
187
- if(response.status >= 200 && response.status < 300) {
270
+ if(response && response.status >= 200 && response.status < 300) {
188
271
  const body = await response.json();
189
- newMsg.payload = body
190
- node.send(JSON.parse(JSON.stringify(newMsg)));
272
+ msg.payload = body
273
+ node.send(msg);
191
274
  } else {
192
- let payload = {}
193
- payload.status = response.status
194
- payload.text = await response.text()
195
-
196
- newMsg.payload = payload
197
- node.send(JSON.parse(JSON.stringify(newMsg)));
275
+ if (!response) {
276
+ node.error('Request failed after all attempts.');
277
+ msg.error = 'Request failed after all attempts.'
278
+ msg.payload = null;
279
+ if(msg.res){
280
+ msg.payload = JSON.stringify('Request failed after all attempts.');
281
+ msg.statusCode = 500;
282
+ }
283
+ node.send(msg);
284
+ } else {
285
+ node.error('Response status: ' + response.status);
286
+ node.error('Response text: ' + await response.text());
287
+ }
198
288
  }
199
289
  }
200
290
  } catch (e) {
@@ -202,7 +292,7 @@ module.exports = function(RED) {
202
292
  }
203
293
  }
204
294
 
205
- const r = await doAsyncJobs()
295
+ await doAsyncJobs();
206
296
 
207
297
  } catch (e) {
208
298
  node.error(e);
@@ -285,4 +375,4 @@ module.exports = function(RED) {
285
375
  }
286
376
 
287
377
  RED.nodes.registerType("teamogy-client",teamogyClient);
288
- }
378
+ }