<?phpnamespace App\Xapi;/** * A XAPI failure: ["SESSION_AUTHENTICATION_FAILED", "root", "Authentication failure"], ["VM_BAD_POWER_STATE", ...], or a transport * problem (code TRANSPORT). */final class XapiError extends \RuntimeException{ /** @param list<string> $failure */ public function __construct(public array $failure, ?\Throwable $previous = null) { parent::__construct(self::explain($failure), 0, $previous); } public function code(): string { return (string)($this->failure[0] ?? 'UNKNOWN'); } /** @param list<string> $failure */ public static function explain(array $failure): string { $code = (string)($failure[0] ?? 'UNKNOWN'); $args = array_slice($failure, 1); return match ($code) { 'SESSION_AUTHENTICATION_FAILED' => 'Authentication failed: check the user name and the password.', 'HOST_IS_SLAVE' => 'This server is a pool member: connect to its pool master (' . ($args[0] ?? '?') . ').', 'VM_BAD_POWER_STATE' => 'The VM is not in the right power state (expected ' . ($args[1] ?? '?') . ', it is ' . ($args[2] ?? '?') . ').', 'SESSION_INVALID' => 'The session expired: reconnect.', 'TRANSPORT' => (string)($args[0] ?? 'The server cannot be reached.'), 'OPERATION_NOT_ALLOWED' => 'Operation not allowed: ' . implode(' ', $args), 'VM_MISSING_PV_DRIVERS' => 'This VM has no guest tools (PV drivers): use a forced shut down / reboot.', default => $code . ($args !== [] ? ': ' . implode(', ', array_map('strval', $args)) : ''), }; } public static function transport(string $message): self { return new self(['TRANSPORT', $message]); }}