Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e86eabec authored by Ronak Patel's avatar Ronak Patel
Browse files

Try-catch added to handle errors

parent 8b34ecc7
Loading
Loading
Loading
Loading
+129 −61
Original line number Diff line number Diff line
@@ -89,14 +89,19 @@ class SyncMissingUsersToCommon extends Command {
	 */
	private function processUsers(array $usernames, string $ipAddress, bool $isDryRun, OutputInterface $output): array {
		$stats = [
			'total' => 0,
			'processed' => 0,
			'success' => 0,
			'errors' => 0
			'errors' => 0,
			'failed_reasons' => []
		];

		if (!empty($usernames)) {
			$stats['total'] = count($usernames);
			$this->processSpecificUsers($usernames, $ipAddress, $isDryRun, $output, $stats);
		} else {
			// Don't pre-count for all users - it's an expensive operation
			$output->writeln('<info>Processing all users from NextCloud (counting during processing)</info>');
			$this->processAllUsers($ipAddress, $isDryRun, $output, $stats);
		}

@@ -107,10 +112,17 @@ class SyncMissingUsersToCommon extends Command {
	 * Process a list of specific users
	 */
	private function processSpecificUsers(array $usernames, string $ipAddress, bool $isDryRun, OutputInterface $output, array &$stats): void {
		$output->writeln(sprintf('<info>Processing %d specific users</info>', count($usernames)));
		$output->writeln(sprintf('<info>Processing %d specific users</info>', $stats['total']));
		
		foreach ($usernames as $username) {
			try {
				$this->processSingleUser($username, $ipAddress, $isDryRun, $output, $stats);
			} catch (Exception $e) {
				$errorMessage = sprintf('Unexpected error processing user %s: %s', $username, $e->getMessage());
				$output->writeln(sprintf('<error>%s</error>', $errorMessage));
				$stats['errors']++;
				$stats['failed_reasons'][] = $errorMessage;
			}
		}
	}

@@ -118,52 +130,92 @@ class SyncMissingUsersToCommon extends Command {
	 * Process all users from NextCloud
	 */
	private function processAllUsers(string $ipAddress, bool $isDryRun, OutputInterface $output, array &$stats): void {
		$userCount = 0;
		$output->writeln('<info>Processing all users from NextCloud</info>');

		$this->userManager->callForAllUsers(function (IUser $user) use (&$userCount, $ipAddress, $isDryRun, $output, &$stats) {
		$this->userManager->callForAllUsers(function (IUser $user) use ($ipAddress, $isDryRun, $output, &$stats) {
			try {
				$this->processSingleUser($user->getUID(), $ipAddress, $isDryRun, $output, $stats);
			$userCount++;
			if ($userCount > 0 && $userCount % 100 === 0) {
				
				// Reduce output frequency for better performance
				if ($stats['processed'] > 0 && $stats['processed'] % 1000 === 0) {
					$output->writeln(sprintf('<info>Progress: %d processed, %d success, %d errors</info>',
					$userCount, $stats['success'], $stats['errors']));
						$stats['processed'], $stats['success'], $stats['errors']));
				}
			} catch (Exception $e) {
				$errorMessage = sprintf('Unexpected error processing user %s: %s', $user->getUID(), $e->getMessage());
				$output->writeln(sprintf('<error>%s</error>', $errorMessage));
				$stats['errors']++;
				$stats['failed_reasons'][] = $errorMessage;
			}
		});
		
		// Set total after processing for all users
		$stats['total'] = $stats['processed'];
	}

	/**
	 * Process a single user
	 */
	private function processSingleUser(string $username, string $ipAddress, bool $isDryRun, OutputInterface $output, array &$stats): void {
		$stats['processed']++; // Increment processed count first for all users
		
		try {
			$user = $this->userManager->get($username);
			if (!$user) {
			$output->writeln(sprintf('<error>User not found: %s</error>', $username));
				$errorMessage = sprintf('User not found: %s', $username);
				$output->writeln(sprintf('<error>%s</error>', $errorMessage));
				$stats['errors']++;
				$stats['failed_reasons'][] = $errorMessage;
				return;
			}

			// Strip legacy domain from username before checking in common DB
			$usernameWithoutDomain = $this->userService->stripLegacyDomainFromUsername($username);
			if ($this->userService->isUsernameTaken($usernameWithoutDomain)) {
			return; // Skip if already exists
				// This is not an error, just a skip - user already exists
				return;
			}

		try {
			$this->syncUserToCommon($username, $ipAddress, $isDryRun, $output);
			$stats['success']++;
		} catch (Exception $e) {
			$output->writeln(sprintf('<error>Error syncing user %s: %s</error>', $username, $e->getMessage()));
			$errorMessage = sprintf('Error processing user %s: %s', $username, $e->getMessage());
			$output->writeln(sprintf('<error>%s</error>', $errorMessage));
			$stats['errors']++;
			$stats['failed_reasons'][] = $errorMessage;
		}
		$stats['processed']++;
	}

	/**
	 * Display final results
	 */
	private function displayFinalResults(array $stats, OutputInterface $output): void {
		$output->writeln(sprintf('<info>Final result: %d users processed, %d success, %d errors.</info>',
			$stats['processed'], $stats['success'], $stats['errors']));
		$output->writeln('');
		$output->writeln('<info>=== FINAL RESULTS ===</info>');
		$output->writeln(sprintf('<info>Total users to process: %d</info>', $stats['total']));
		$output->writeln(sprintf('<info>Users processed: %d</info>', $stats['processed']));
		$output->writeln(sprintf('<info>Successfully synced: %d</info>', $stats['success']));
		$output->writeln(sprintf('<info>Errors encountered: %d</info>', $stats['errors']));
		
		if (!empty($stats['failed_reasons'])) {
			$output->writeln('');
			$output->writeln('<error>=== FAILURE REASONS ===</error>');
			
			// Limit the number of reasons shown for performance
			$maxReasonsToShow = 50;
			$reasonsToShow = array_slice($stats['failed_reasons'], 0, $maxReasonsToShow);
			
			foreach ($reasonsToShow as $reason) {
				$output->writeln(sprintf('<error>• %s</error>', $reason));
			}
			
			if (count($stats['failed_reasons']) > $maxReasonsToShow) {
				$remaining = count($stats['failed_reasons']) - $maxReasonsToShow;
				$output->writeln(sprintf('<error>... and %d more errors.</error>', $remaining));
			}
		}
		
		$output->writeln('');
		$output->writeln(sprintf('<info>Summary: %d/%d users processed successfully</info>',
			$stats['success'], $stats['total']));
	}

	/**
@@ -176,16 +228,22 @@ class SyncMissingUsersToCommon extends Command {
	 * @return void
	 */
	private function syncUserToCommon(string $username, string $ipAddress, bool $isDryRun, OutputInterface $output): void {
		// Only show processing message in dry run mode for performance
		if ($isDryRun) {
			$output->writeln(sprintf('Processing user: %s', $username));
		}

		// Check if user exists and is on LDAP backend
		try {
			// Get user from userManager (already verified to exist in processSingleUser)
			$user = $this->userManager->get($username);
		if (!$user) {
			throw new Exception("User not found in NextCloud");
		}

			// Check if user is on LDAP backend - skip if not
			if (!$this->ldapConnectionService->isUserOnLDAPBackend($user)) {
			throw new Exception("User is not on LDAP backend");
				// Skip users that are not on LDAP backend
				if ($isDryRun) {
					$output->writeln(sprintf('  <comment>Skipping user %s: not on LDAP backend</comment>', $username));
				}
				return; // Skip this user gracefully
			}

			// Get user metadata from LDAP
@@ -205,7 +263,10 @@ class SyncMissingUsersToCommon extends Command {
				}
			}

			// Only show detailed output in dry run mode
			if ($isDryRun) {
				$output->writeln(sprintf('  Found user in LDAP: %s (created: %s)', $usernameWithoutDomain, $createdAt));
			}

			if (!$isDryRun) {
				// Add user to common database
@@ -215,9 +276,16 @@ class SyncMissingUsersToCommon extends Command {
					$userMetadata['recoveryMailAddress'],
					$createdAt
				);
				// Only show success message in dry run mode for performance
				if ($isDryRun) {
					$output->writeln(sprintf('  <info>✓ User synced successfully to common database: %s</info>', $usernameWithoutDomain));
				}
			} else {
				$output->writeln(sprintf('  <comment>Would sync user to common database with recovery email: %s and created_at: %s</comment>', $userMetadata['recoveryMailAddress'], $createdAt));
			}
		} catch (Exception $e) {
			// Re-throw the exception to be caught by the caller
			throw new Exception(sprintf("Failed to sync user %s: %s", $username, $e->getMessage()), 0, $e);
		}
	}
}