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
- if (!calc || typeof calc.getResult !== 'function') continue;
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
- const result = await Promise.resolve(calc.getResult());
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
- // --- THIS IS THE FIX ---
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
- logger.log('ERROR', `[${passName}] getResult/Commit failed for ${calcName} on ${dateStr}`, { err: e.message });
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 still important, as it indicates a logic error
683
- // if a calc *wasn't* skipped by the orchestrator but its
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
- computedDependencies[normalizedDepName] = dailyResultsCache.get(normalizedDepName);
723
+ // --- END NEW CHECK ---
724
+
725
+ computedDependencies[normalizedDepName] = depResult;
690
726
  }
691
727
  }
692
- if (missingDep) continue;
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
- const result = await Promise.resolve(instance.process(
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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.112",
3
+ "version": "1.0.114",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [