Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions plugins/video_gen/xai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,15 +520,23 @@ def _run_xai_video_coroutine(
except Exception as exc:
logger.warning("xAI video %s unexpected failure: %s", operation_label, exc, exc_info=True)
return error_response(
error=f"xAI video {operation_label} failed: {exc}",
error_type="api_error",
error=f"xAI video {operation_label} failed: {type(exc).__name__}: {exc}",
error_type=_xai_video_wrapper_error_type(exc),
provider="xai",
model=model or DEFAULT_MODEL,
prompt=prompt,
aspect_ratio=aspect_ratio,
)


def _xai_video_wrapper_error_type(exc: Exception) -> str:
if isinstance(exc, (TimeoutError, httpx.TimeoutException)):
return "timeout"
if isinstance(exc, httpx.TransportError):
return "connection_error"
return "api_error"


async def _generate_xai_video_async(
*,
prompt: str,
Expand Down
40 changes: 40 additions & 0 deletions tests/plugins/video_gen/test_xai_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,46 @@ def test_xai_no_operation_kwarg():
assert result["error_type"] in {"auth_required", "api_error"}


def test_xai_video_wrapper_preserves_read_timeout_error_type():
import httpx
from plugins.video_gen.xai import _run_xai_video_coroutine

async def fail_with_timeout():
raise httpx.ReadTimeout("")

result = _run_xai_video_coroutine(
fail_with_timeout(),
operation_label="generation",
model="grok-imagine-video",
prompt="animate the selected image",
aspect_ratio="16:9",
)

assert result["success"] is False
assert result["error_type"] == "timeout"
assert "ReadTimeout" in result["error"]


def test_xai_video_wrapper_preserves_transport_error_type():
import httpx
from plugins.video_gen.xai import _run_xai_video_coroutine

async def fail_with_transport_error():
raise httpx.ConnectError("network unavailable")

result = _run_xai_video_coroutine(
fail_with_transport_error(),
operation_label="generation",
model="grok-imagine-video",
prompt="animate the selected image",
aspect_ratio="16:9",
)

assert result["success"] is False
assert result["error_type"] == "connection_error"
assert "ConnectError" in result["error"]


def test_xai_video_output_urls_prefers_stored_public_url():
from plugins.video_gen.xai import _xai_video_output_urls

Expand Down