bulltrackers-module 1.0.533 → 1.0.535
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.
|
@@ -257,7 +257,13 @@ async function handleRequest(message, context, configObj, dependencies) {
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
} catch (err) {
|
|
260
|
-
|
|
260
|
+
const errorMessage = err.message || String(err);
|
|
261
|
+
const errorStack = err.stack || '';
|
|
262
|
+
logger.log('ERROR', `[TaskEngine] Error processing task ${type}: ${errorMessage}`, {
|
|
263
|
+
error: errorMessage,
|
|
264
|
+
stack: errorStack,
|
|
265
|
+
taskType: type
|
|
266
|
+
});
|
|
261
267
|
}
|
|
262
268
|
}
|
|
263
269
|
|
|
@@ -27,17 +27,26 @@ async function fetchWithRetry(url, options, proxyManager, logger, label) {
|
|
|
27
27
|
if (res.ok) {
|
|
28
28
|
recordProxyOutcome(true);
|
|
29
29
|
return res;
|
|
30
|
+
} else {
|
|
31
|
+
// Log proxy failure with details
|
|
32
|
+
const errorText = await res.text().catch(() => 'Unable to read response');
|
|
33
|
+
logger.log('WARN', `[${label}] Proxy returned status ${res.status} for ${url}. Response: ${errorText.substring(0, 200)}`);
|
|
34
|
+
recordProxyOutcome(false);
|
|
30
35
|
}
|
|
31
36
|
} catch (e) {
|
|
32
37
|
recordProxyOutcome(false);
|
|
33
|
-
logger.log('WARN', `[${label}] Proxy failed. Retrying direct.`);
|
|
38
|
+
logger.log('WARN', `[${label}] Proxy failed for ${url}: ${e.message}. Retrying direct.`);
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
// Fallback
|
|
38
43
|
const directFetch = typeof fetch !== 'undefined' ? fetch : require('node-fetch');
|
|
39
44
|
const res = await directFetch(url, options);
|
|
40
|
-
if (!res.ok)
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const errorText = await res.text().catch(() => 'Unable to read response');
|
|
47
|
+
logger.log('ERROR', `[${label}] Direct fetch failed for ${url}: Status ${res.status}. Response: ${errorText.substring(0, 200)}`);
|
|
48
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText} - ${errorText.substring(0, 100)}`);
|
|
49
|
+
}
|
|
41
50
|
return res;
|
|
42
51
|
}
|
|
43
52
|
|
|
@@ -57,6 +66,8 @@ async function processPortfolio(context, config, taskData, isPI) {
|
|
|
57
66
|
const { cid, username, uuid, today, requestOptions } = taskData;
|
|
58
67
|
const url = `${config.ETORO_API_PORTFOLIO_URL}?cid=${cid}&client_request_id=${uuid}`;
|
|
59
68
|
|
|
69
|
+
logger.log('INFO', `[Portfolio] Fetching ${isPI ? 'PI' : 'Signed-In User'} portfolio from: ${url}`);
|
|
70
|
+
|
|
60
71
|
const res = await fetchWithRetry(url, requestOptions, proxyManager, logger, 'Portfolio');
|
|
61
72
|
const data = await res.json();
|
|
62
73
|
data.fetchedAt = new Date();
|
|
@@ -235,15 +246,26 @@ async function handleGenericUserUpdate(taskData, config, dependencies, isPI) {
|
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
} catch (err) {
|
|
238
|
-
|
|
249
|
+
// Log error with full details
|
|
250
|
+
const errorMessage = err.message || String(err);
|
|
251
|
+
const errorStack = err.stack || '';
|
|
252
|
+
logger.log('ERROR', `[Update] Failed for ${username}: ${errorMessage}`, {
|
|
253
|
+
error: errorMessage,
|
|
254
|
+
stack: errorStack,
|
|
255
|
+
cid,
|
|
256
|
+
username,
|
|
257
|
+
requestId,
|
|
258
|
+
isPI
|
|
259
|
+
});
|
|
260
|
+
|
|
239
261
|
// Mark Failed
|
|
240
262
|
if (requestId && db) {
|
|
241
263
|
const reqRef = db.collection(source === 'on_demand_sync' ? 'user_sync_requests' : 'pi_fetch_requests')
|
|
242
264
|
.doc(String(cid)).collection('requests').doc(requestId);
|
|
243
|
-
await reqRef.update({ status: 'failed', error:
|
|
265
|
+
await reqRef.update({ status: 'failed', error: errorMessage, failedAt: FieldValue.serverTimestamp() });
|
|
244
266
|
|
|
245
267
|
if (metadata?.requestingUserCid) {
|
|
246
|
-
notifyTaskEngineComplete(db, logger, metadata.requestingUserCid, requestId, username, false,
|
|
268
|
+
notifyTaskEngineComplete(db, logger, metadata.requestingUserCid, requestId, username, false, errorMessage).catch(()=>{});
|
|
247
269
|
}
|
|
248
270
|
}
|
|
249
271
|
throw err;
|
|
@@ -427,7 +449,9 @@ async function handlePopularInvestorUpdate(taskData, config, dependencies) {
|
|
|
427
449
|
}
|
|
428
450
|
|
|
429
451
|
async function handleOnDemandUserUpdate(taskData, config, dependencies) {
|
|
430
|
-
|
|
452
|
+
// Use the same public portfolio endpoint as PIs - signed-in users can also use public endpoints
|
|
453
|
+
// The endpoint /sapi/portfolios/portfolio doesn't exist (404)
|
|
454
|
+
config.ETORO_API_PORTFOLIO_URL = config.ETORO_API_PORTFOLIO_URL || 'https://www.etoro.com/sapi/trade-data-real/live/public/portfolios';
|
|
431
455
|
config.ETORO_API_HISTORY_URL = config.ETORO_API_HISTORY_URL || 'https://www.etoro.com/sapi/trade-data-real/history/public/credit/flat';
|
|
432
456
|
|
|
433
457
|
return handleGenericUserUpdate(taskData, config, dependencies, false);
|