bulltrackers-module 1.0.112 → 1.0.114
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.
|
@@ -532,19 +532,35 @@ async function runUnifiedComputation(dateToProcess, calculationsToRun, passName,
|
|
|
532
532
|
|
|
533
533
|
for (const calcName in state) { // calcName is already normalized
|
|
534
534
|
const calc = state[calcName];
|
|
535
|
-
|
|
535
|
+
|
|
536
|
+
// --- START FIX ---
|
|
537
|
+
// Ensure every calc from the state has a result (null by default)
|
|
538
|
+
// This prevents the "Missing dependency" error downstream
|
|
539
|
+
// if the calculation failed to initialize.
|
|
540
|
+
passResults[calcName] = null;
|
|
541
|
+
// --- END FIX ---
|
|
542
|
+
|
|
543
|
+
if (!calc || typeof calc.getResult !== 'function') {
|
|
544
|
+
if (!calc) {
|
|
545
|
+
logger.log('WARN', `[${passName}] Skipping ${calcName} for ${dateStr} because it failed to initialize (check manifest/class).`);
|
|
546
|
+
}
|
|
547
|
+
continue; // Skip to the next calculation
|
|
548
|
+
}
|
|
536
549
|
|
|
537
550
|
const category = calc.manifest.category || 'unknown';
|
|
538
551
|
|
|
552
|
+
// --- FINAL FIX: THIS IS THE MODIFIED BLOCK ---
|
|
553
|
+
let result = null; // Default to null
|
|
539
554
|
try {
|
|
540
|
-
|
|
555
|
+
// This is where the calculation runs. It might return null
|
|
556
|
+
// OR it might THROW AN ERROR (e.g., Firestore error).
|
|
557
|
+
result = await Promise.resolve(calc.getResult());
|
|
541
558
|
|
|
542
|
-
//
|
|
543
|
-
// We MUST cache the result, even if it is null,
|
|
544
|
-
// so that downstream calculations know it ran.
|
|
559
|
+
// Cache the successful result (even if it's null)
|
|
545
560
|
passResults[calcName] = result;
|
|
546
|
-
// --- END FIX ---
|
|
547
561
|
|
|
562
|
+
// --- Database write logic ---
|
|
563
|
+
// (This only runs if getResult() did NOT throw an error)
|
|
548
564
|
const pendingWrites = [];
|
|
549
565
|
const summaryData = {};
|
|
550
566
|
|
|
@@ -603,19 +619,26 @@ async function runUnifiedComputation(dateToProcess, calculationsToRun, passName,
|
|
|
603
619
|
successCount++;
|
|
604
620
|
}
|
|
605
621
|
} else {
|
|
606
|
-
// --- MODIFICATION: Do not log a warning if the result is null. ---
|
|
607
|
-
// This is now expected behavior if a calc (like user-profitability-tracker)
|
|
608
|
-
// has no data to process.
|
|
609
|
-
// We *do* still need to log if a result is empty.
|
|
610
622
|
if (result === null) {
|
|
611
623
|
logger.log('INFO', `[${passName}] Calculation ${calcName} returned null for ${dateStr}. This is expected if no data was processed.`);
|
|
612
624
|
} else {
|
|
613
625
|
logger.log('WARN', `[${passName}] Calculation ${calcName} produced empty results {} for ${dateStr}. Skipping write.`);
|
|
614
626
|
}
|
|
615
627
|
}
|
|
628
|
+
// --- End of DB write logic ---
|
|
629
|
+
|
|
616
630
|
} catch (e) {
|
|
617
|
-
|
|
631
|
+
// --- THIS IS THE CRITICAL FIX ---
|
|
632
|
+
// The calculation *threw an error*.
|
|
633
|
+
// Log the real error.
|
|
634
|
+
logger.log('ERROR', `[${passName}] getResult/Commit failed for ${calcName} on ${dateStr}`, { err: e.message, stack: e.stack });
|
|
635
|
+
|
|
636
|
+
// NOW, *still cache null* so downstream dependencies
|
|
637
|
+
// can see the failure and skip gracefully.
|
|
638
|
+
passResults[calcName] = null;
|
|
639
|
+
// --- END CRITICAL FIX ---
|
|
618
640
|
}
|
|
641
|
+
// --- END FINAL FIX BLOCK ---
|
|
619
642
|
}
|
|
620
643
|
|
|
621
644
|
const completionStatus = successCount === calculationsToRun.length ? 'SUCCESS' : 'WARN';
|
|
@@ -669,38 +692,59 @@ async function runMetaComputation(
|
|
|
669
692
|
|
|
670
693
|
const instance = new CalcClass();
|
|
671
694
|
|
|
695
|
+
// --- MODIFICATION: Wrap meta-calc process in try/catch ---
|
|
696
|
+
let result = null; // Default to null
|
|
672
697
|
try {
|
|
673
698
|
// --- Gather dependencies from the cache ---
|
|
674
|
-
// This check is now more robust, as the orchestrator has already
|
|
675
|
-
// logged the *reason* for a skip. We just need to check the cache.
|
|
676
699
|
const computedDependencies = {};
|
|
677
700
|
let missingDep = false;
|
|
678
701
|
if (manifestCalc.dependencies) {
|
|
679
702
|
for (const depName of manifestCalc.dependencies) {
|
|
680
703
|
const normalizedDepName = normalizeName(depName);
|
|
704
|
+
|
|
705
|
+
// --- THIS IS THE LOGIC THAT IS FAILING ---
|
|
681
706
|
if (!dailyResultsCache.has(normalizedDepName)) {
|
|
682
|
-
// This log is
|
|
683
|
-
//
|
|
684
|
-
// dependency is *still* missing (e.g., the dep returned null).
|
|
707
|
+
// This log is now correct. The dependency is "missing"
|
|
708
|
+
// because the upstream calc *failed* and was skipped.
|
|
685
709
|
logger.log('ERROR', `[${passName}] Missing required dependency "${normalizedDepName}" for calculation "${calcName}". This should not happen. Skipping calc.`);
|
|
686
710
|
missingDep = true;
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// --- NEW CHECK ---
|
|
715
|
+
// Check if the dependency *exists* but is `null` (due to no data or failure)
|
|
716
|
+
const depResult = dailyResultsCache.get(normalizedDepName);
|
|
717
|
+
if (depResult === null) {
|
|
718
|
+
// This is a *graceful* skip, not an error.
|
|
719
|
+
logger.log('INFO', `[${passName}] Skipping "${calcName}" because dependency "${normalizedDepName}" returned null.`);
|
|
720
|
+
missingDep = true; // Set to true to skip
|
|
687
721
|
break;
|
|
688
722
|
}
|
|
689
|
-
|
|
723
|
+
// --- END NEW CHECK ---
|
|
724
|
+
|
|
725
|
+
computedDependencies[normalizedDepName] = depResult;
|
|
690
726
|
}
|
|
691
727
|
}
|
|
692
|
-
if (missingDep)
|
|
728
|
+
if (missingDep) {
|
|
729
|
+
// This calc is skipped, so its result is `null`
|
|
730
|
+
passResults[calcName] = null;
|
|
731
|
+
continue; // Skip to the next calculation
|
|
732
|
+
}
|
|
733
|
+
// --- End Dependency Check ---
|
|
734
|
+
|
|
693
735
|
|
|
694
736
|
// --- Call process with the dependencies ---
|
|
695
|
-
|
|
737
|
+
result = await Promise.resolve(instance.process(
|
|
696
738
|
dateStr,
|
|
697
739
|
dependenciesForMetaCalc,
|
|
698
740
|
config,
|
|
699
741
|
computedDependencies
|
|
700
742
|
));
|
|
701
743
|
|
|
744
|
+
// Cache the result (even if it's null)
|
|
702
745
|
passResults[calcName] = result;
|
|
703
746
|
|
|
747
|
+
// --- Database write logic ---
|
|
704
748
|
const pendingWrites = [];
|
|
705
749
|
const summaryData = {};
|
|
706
750
|
|
|
@@ -730,9 +774,16 @@ async function runMetaComputation(
|
|
|
730
774
|
} else {
|
|
731
775
|
logger.log('WARN', `[${passName}] Meta-calculation ${calcName} produced no results for ${dateStr}. Skipping write.`);
|
|
732
776
|
}
|
|
777
|
+
// --- End DB Write ---
|
|
778
|
+
|
|
733
779
|
} catch (e) {
|
|
780
|
+
// --- THIS IS THE CRITICAL FIX for meta-calcs ---
|
|
734
781
|
logger.log('ERROR', `[${passName}] Meta-calc process/commit failed for ${calcName} on ${dateStr}`, { err: e.message, stack: e.stack });
|
|
782
|
+
// Cache null on failure
|
|
783
|
+
passResults[calcName] = null;
|
|
784
|
+
// --- END FIX ---
|
|
735
785
|
}
|
|
786
|
+
// --- END MODIFICATION ---
|
|
736
787
|
}
|
|
737
788
|
|
|
738
789
|
const completionStatus = successCount === calculationsToRun.length ? 'SUCCESS' : 'WARN';
|