mirror of
https://github.com/Dasemu/x-space-downloader.git
synced 2026-10-13 21:49:45 +00:00
feat: add error handling to downloader
Added DownloadError exception class that is raised when yt-dlp fails. The download_space function now wraps yt-dlp calls in a try-except block to catch any exceptions and raise a custom DownloadError with a clear message. Test added to verify that DownloadError is raised when yt-dlp fails. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,11 @@ from typing import Optional
|
||||
from src.validator import validate_space_url
|
||||
|
||||
|
||||
class DownloadError(Exception):
|
||||
"""Raised when download fails."""
|
||||
pass
|
||||
|
||||
|
||||
def download_space(
|
||||
space_url: str,
|
||||
output_dir: str,
|
||||
@@ -19,6 +24,9 @@ def download_space(
|
||||
|
||||
Returns:
|
||||
Path to the downloaded MP3 file
|
||||
|
||||
Raises:
|
||||
DownloadError: If download fails
|
||||
"""
|
||||
# Extract space ID from URL using validator for robustness
|
||||
is_valid, space_id, error_message = validate_space_url(space_url)
|
||||
@@ -45,8 +53,11 @@ def download_space(
|
||||
ydl_opts['cookiefile'] = cookies_file
|
||||
|
||||
# Download with yt-dlp
|
||||
try:
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
ydl.extract_info(space_url, download=True)
|
||||
except Exception as e:
|
||||
raise DownloadError(f"Failed to download Space: {str(e)}")
|
||||
|
||||
# Return the expected output path
|
||||
return os.path.join(output_dir, f'space_{space_id}.mp3')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from src.downloader import download_space
|
||||
from src.downloader import download_space, DownloadError
|
||||
|
||||
|
||||
def test_download_space_basic(tmp_path):
|
||||
@@ -83,3 +83,22 @@ def test_download_space_ytdlp_configuration(tmp_path):
|
||||
assert len(call_args['postprocessors']) > 0
|
||||
assert call_args['postprocessors'][0]['key'] == 'FFmpegExtractAudio'
|
||||
assert call_args['postprocessors'][0]['preferredcodec'] == 'mp3'
|
||||
|
||||
|
||||
def test_download_space_error_handling(tmp_path):
|
||||
"""Test that download errors are properly caught and wrapped."""
|
||||
space_url = "https://x.com/i/spaces/invalid"
|
||||
|
||||
with patch('src.downloader.yt_dlp.YoutubeDL') as mock_ytdl_class:
|
||||
mock_ytdl = Mock()
|
||||
mock_ytdl_class.return_value.__enter__.return_value = mock_ytdl
|
||||
mock_ytdl.extract_info.side_effect = Exception("Video unavailable")
|
||||
|
||||
with pytest.raises(DownloadError) as exc_info:
|
||||
download_space(
|
||||
space_url=space_url,
|
||||
output_dir=str(tmp_path),
|
||||
cookies_file=None
|
||||
)
|
||||
|
||||
assert "Failed to download" in str(exc_info.value)
|
||||
|
||||
Reference in New Issue
Block a user