getMessage(); // Check if it's retryable and not the last attempt if ($this->isRetryableSshError($lastErrorMessage) && $attempt < $maxRetries - 1) { $delay = $this->calculateRetryDelay($attempt); // Add deployment log if available (for ExecuteRemoteCommand trait) if (isset($this->application_deployment_queue) && method_exists($this, 'addRetryLogEntry')) { $this->addRetryLogEntry($attempt + 1, $maxRetries, $delay, $lastErrorMessage); } sleep($delay); continue; } // Not retryable or max retries reached break; } } // All retries exhausted if ($attempt >= $maxRetries) { Log::error('SSH operation failed after all retries', array_merge($context, [ 'attempts' => $attempt, 'error' => $lastErrorMessage, ])); } if ($throwError && $lastError) { // If the error message is empty, provide a more meaningful one if (empty($lastErrorMessage) || trim($lastErrorMessage) === '') { $contextInfo = isset($context['server']) ? " to server {$context['server']}" : ''; $attemptInfo = $attempt > 1 ? " after {$attempt} attempts" : ''; throw new \RuntimeException("SSH connection failed{$contextInfo}{$attemptInfo}", $lastError->getCode()); } throw $lastError; } return null; } }