or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

captions.mdcollections.mdexceptions.mdindex.mdstream-management.mdvideo-downloads.md

exceptions.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy for handling various error conditions including video availability, network issues, extraction failures, and other operational errors in pytube.

3

4

## Capabilities

5

6

### Base Exception

7

8

Root exception class for all pytube-specific errors.

9

10

```python { .api }

11

class PytubeError(Exception):

12

"""

13

Base exception class for all pytube errors.

14

15

All other pytube exceptions inherit from this base class,

16

allowing for comprehensive error handling.

17

"""

18

```

19

20

### Network and Retry Exceptions

21

22

Exceptions related to network operations and request failures.

23

24

```python { .api }

25

class MaxRetriesExceeded(PytubeError):

26

"""

27

Exception raised when maximum retry attempts are exceeded.

28

29

Occurs during download operations when network requests

30

fail repeatedly beyond the configured retry limit.

31

"""

32

```

33

34

### HTML Parsing and Data Extraction Exceptions

35

36

Exceptions related to parsing YouTube pages and extracting video data.

37

38

```python { .api }

39

class HTMLParseError(PytubeError):

40

"""

41

Exception raised when HTML parsing fails.

42

43

Occurs when pytube cannot parse YouTube page content,

44

often due to page structure changes or malformed HTML.

45

"""

46

47

class ExtractError(PytubeError):

48

"""

49

Exception raised when data extraction fails.

50

51

General exception for failures in extracting video information,

52

stream data, or metadata from YouTube responses.

53

"""

54

55

class RegexMatchError(ExtractError):

56

def __init__(self, caller: str, pattern: Union[str, Pattern]):

57

"""

58

Exception raised when regular expression matching fails.

59

60

Args:

61

caller (str): The function or method where the regex failed

62

pattern (str or Pattern): The regex pattern that failed to match

63

"""

64

```

65

66

### Video Availability Exceptions

67

68

Base class and specific exceptions for various video availability issues.

69

70

```python { .api }

71

class VideoUnavailable(PytubeError):

72

def __init__(self, video_id: str):

73

"""

74

Base exception for video unavailability issues.

75

76

Args:

77

video_id (str): The YouTube video ID that is unavailable

78

"""

79

80

class AgeRestrictedError(VideoUnavailable):

81

def __init__(self, video_id: str):

82

"""

83

Exception raised when video is age-restricted.

84

85

Occurs when attempting to access age-restricted content

86

without proper authentication or when content has

87

tier 3 age restrictions that cannot be bypassed.

88

89

Args:

90

video_id (str): The age-restricted video ID

91

"""

92

93

class LiveStreamError(VideoUnavailable):

94

def __init__(self, video_id: str):

95

"""

96

Exception raised when attempting to download live streams.

97

98

Live streams cannot be downloaded as they are ongoing

99

broadcasts without fixed content.

100

101

Args:

102

video_id (str): The live stream video ID

103

"""

104

105

class VideoPrivate(VideoUnavailable):

106

def __init__(self, video_id: str):

107

"""

108

Exception raised when video is private.

109

110

Occurs when attempting to access private videos that

111

require specific permissions or are only visible to

112

the uploader.

113

114

Args:

115

video_id (str): The private video ID

116

"""

117

118

class RecordingUnavailable(VideoUnavailable):

119

def __init__(self, video_id: str):

120

"""

121

Exception raised when live stream recording is unavailable.

122

123

Occurs when a live stream has ended but the recording

124

is not yet available or has been disabled.

125

126

Args:

127

video_id (str): The unavailable recording video ID

128

"""

129

130

class MembersOnly(VideoUnavailable):

131

def __init__(self, video_id: str):

132

"""

133

Exception raised when video is members-only content.

134

135

Occurs when attempting to access content restricted

136

to channel members without proper membership status.

137

138

Args:

139

video_id (str): The members-only video ID

140

"""

141

142

class VideoRegionBlocked(VideoUnavailable):

143

def __init__(self, video_id: str):

144

"""

145

Exception raised when video is blocked in the user's region.

146

147

Occurs when content is geo-restricted and not available

148

in the user's geographic location.

149

150

Args:

151

video_id (str): The region-blocked video ID

152

"""

153

```

154

155

## Usage Examples

156

157

### Basic Exception Handling

158

159

```python

160

from pytube import YouTube

161

from pytube.exceptions import VideoUnavailable, AgeRestrictedError, PytubeError

162

163

def safe_download(video_url):

164

"""Download video with comprehensive error handling."""

165

try:

166

yt = YouTube(video_url)

167

stream = yt.streams.get_highest_resolution()

168

169

if stream:

170

file_path = stream.download()

171

print(f"Successfully downloaded: {file_path}")

172

return file_path

173

else:

174

print("No suitable stream found")

175

return None

176

177

except VideoUnavailable as e:

178

print(f"Video unavailable: {e}")

179

return None

180

except AgeRestrictedError as e:

181

print(f"Age-restricted content: {e}")

182

return None

183

except PytubeError as e:

184

print(f"Pytube error: {e}")

185

return None

186

except Exception as e:

187

print(f"Unexpected error: {e}")

188

return None

189

190

# Usage

191

result = safe_download('https://www.youtube.com/watch?v=VIDEO_ID')

192

```

193

194

### Specific Exception Handling

195

196

```python

197

from pytube import YouTube

198

from pytube.exceptions import (

199

VideoPrivate, MembersOnly, LiveStreamError,

200

RecordingUnavailable, VideoRegionBlocked

201

)

202

203

def handle_specific_errors(video_url):

204

"""Handle specific video availability issues."""

205

try:

206

yt = YouTube(video_url)

207

return yt.streams.get_highest_resolution()

208

209

except VideoPrivate:

210

print("This video is private and cannot be accessed")

211

return None

212

213

except MembersOnly:

214

print("This video is for channel members only")

215

print("Consider becoming a channel member to access this content")

216

return None

217

218

except LiveStreamError:

219

print("Cannot download live streams - wait for the recording")

220

return None

221

222

except RecordingUnavailable:

223

print("Live stream recording not yet available")

224

return None

225

226

except VideoRegionBlocked:

227

print("Video is blocked in your region")

228

print("Consider using a VPN or proxy")

229

return None

230

231

# Usage

232

stream = handle_specific_errors('https://www.youtube.com/watch?v=VIDEO_ID')

233

```

234

235

### Retry Logic with Exception Handling

236

237

```python

238

from pytube import YouTube

239

from pytube.exceptions import MaxRetriesExceeded, ExtractError, HTMLParseError

240

import time

241

import random

242

243

def download_with_retry(video_url, max_attempts=3):

244

"""Download with custom retry logic."""

245

246

for attempt in range(max_attempts):

247

try:

248

print(f"Attempt {attempt + 1}/{max_attempts}")

249

250

yt = YouTube(video_url)

251

stream = yt.streams.get_highest_resolution()

252

253

if stream:

254

file_path = stream.download()

255

print(f"Download successful: {file_path}")

256

return file_path

257

258

except MaxRetriesExceeded:

259

print(f"Max retries exceeded on attempt {attempt + 1}")

260

if attempt < max_attempts - 1:

261

wait_time = random.uniform(1, 3) * (attempt + 1)

262

print(f"Waiting {wait_time:.1f} seconds before retry...")

263

time.sleep(wait_time)

264

265

except (ExtractError, HTMLParseError) as e:

266

print(f"Extraction/parsing error on attempt {attempt + 1}: {e}")

267

if attempt < max_attempts - 1:

268

print("Retrying with fresh YouTube object...")

269

time.sleep(2)

270

271

except Exception as e:

272

print(f"Unexpected error: {e}")

273

break

274

275

print("All attempts failed")

276

return None

277

278

# Usage

279

result = download_with_retry('https://www.youtube.com/watch?v=VIDEO_ID')

280

```

281

282

### Bulk Operations with Error Logging

283

284

```python

285

from pytube import Playlist

286

from pytube.exceptions import PytubeError, VideoUnavailable

287

import logging

288

from datetime import datetime

289

290

# Configure logging

291

logging.basicConfig(

292

level=logging.INFO,

293

format='%(asctime)s - %(levelname)s - %(message)s',

294

handlers=[

295

logging.FileHandler('pytube_errors.log'),

296

logging.StreamHandler()

297

]

298

)

299

300

def download_playlist_with_error_logging(playlist_url):

301

"""Download playlist with comprehensive error logging."""

302

303

try:

304

playlist = Playlist(playlist_url)

305

logging.info(f"Starting download of playlist: {playlist.title}")

306

logging.info(f"Total videos: {playlist.length}")

307

308

successful = []

309

failed = []

310

311

for i, video in enumerate(playlist.videos, 1):

312

try:

313

logging.info(f"Processing video {i}/{playlist.length}: {video.title}")

314

315

stream = video.streams.get_highest_resolution()

316

if stream:

317

file_path = stream.download()

318

successful.append({

319

'title': video.title,

320

'url': video.watch_url,

321

'file_path': file_path

322

})

323

logging.info(f"Successfully downloaded: {video.title}")

324

else:

325

raise PytubeError("No suitable stream found")

326

327

except VideoUnavailable as e:

328

error_info = {

329

'title': getattr(video, 'title', 'Unknown'),

330

'url': getattr(video, 'watch_url', 'Unknown'),

331

'error': str(e),

332

'error_type': type(e).__name__

333

}

334

failed.append(error_info)

335

logging.warning(f"Video unavailable: {error_info['title']} - {e}")

336

337

except PytubeError as e:

338

error_info = {

339

'title': getattr(video, 'title', 'Unknown'),

340

'url': getattr(video, 'watch_url', 'Unknown'),

341

'error': str(e),

342

'error_type': type(e).__name__

343

}

344

failed.append(error_info)

345

logging.error(f"Pytube error for {error_info['title']}: {e}")

346

347

except Exception as e:

348

error_info = {

349

'title': getattr(video, 'title', 'Unknown'),

350

'url': getattr(video, 'watch_url', 'Unknown'),

351

'error': str(e),

352

'error_type': type(e).__name__

353

}

354

failed.append(error_info)

355

logging.error(f"Unexpected error for {error_info['title']}: {e}")

356

357

# Summary logging

358

logging.info(f"Download completed - Success: {len(successful)}, Failed: {len(failed)}")

359

360

return {

361

'successful': successful,

362

'failed': failed,

363

'playlist_title': playlist.title

364

}

365

366

except Exception as e:

367

logging.error(f"Failed to process playlist {playlist_url}: {e}")

368

return None

369

370

# Usage

371

results = download_playlist_with_error_logging(

372

'https://www.youtube.com/playlist?list=PLAYLIST_ID'

373

)

374

375

if results:

376

print(f"Playlist: {results['playlist_title']}")

377

print(f"Successful downloads: {len(results['successful'])}")

378

print(f"Failed downloads: {len(results['failed'])}")

379

380

if results['failed']:

381

print("\nFailed downloads:")

382

for failure in results['failed']:

383

print(f"- {failure['title']}: {failure['error_type']}")

384

```

385

386

### Age-Restricted Content Handling

387

388

```python

389

from pytube import YouTube

390

from pytube.exceptions import AgeRestrictedError

391

392

def handle_age_restricted_content(video_url):

393

"""Handle age-restricted content with OAuth fallback."""

394

395

# First attempt without OAuth

396

try:

397

yt = YouTube(video_url)

398

yt.check_availability() # This will raise AgeRestrictedError if needed

399

400

stream = yt.streams.get_highest_resolution()

401

return stream.download()

402

403

except AgeRestrictedError:

404

print("Video is age-restricted, attempting OAuth authentication...")

405

406

try:

407

# Retry with OAuth

408

yt_oauth = YouTube(

409

video_url,

410

use_oauth=True,

411

allow_oauth_cache=True

412

)

413

414

stream = yt_oauth.streams.get_highest_resolution()

415

if stream:

416

return stream.download()

417

else:

418

print("No suitable stream found even with OAuth")

419

return None

420

421

except AgeRestrictedError:

422

print("Content has tier 3 age restrictions and cannot be accessed")

423

return None

424

425

except Exception as e:

426

print(f"OAuth authentication failed: {e}")

427

return None

428

429

# Usage

430

result = handle_age_restricted_content('https://www.youtube.com/watch?v=AGE_RESTRICTED_VIDEO')

431

```

432

433

### Custom Exception Context Manager

434

435

```python

436

from pytube import YouTube

437

from pytube.exceptions import PytubeError

438

from contextlib import contextmanager

439

440

@contextmanager

441

def pytube_error_context(operation_description="pytube operation"):

442

"""Context manager for pytube operations with standardized error handling."""

443

444

try:

445

yield

446

447

except VideoUnavailable as e:

448

print(f"Video unavailable during {operation_description}: {e}")

449

raise

450

451

except AgeRestrictedError as e:

452

print(f"Age-restricted content encountered during {operation_description}: {e}")

453

raise

454

455

except MaxRetriesExceeded as e:

456

print(f"Network issues during {operation_description}: {e}")

457

raise

458

459

except (ExtractError, HTMLParseError) as e:

460

print(f"Data extraction failed during {operation_description}: {e}")

461

raise

462

463

except PytubeError as e:

464

print(f"Pytube error during {operation_description}: {e}")

465

raise

466

467

except Exception as e:

468

print(f"Unexpected error during {operation_description}: {e}")

469

raise

470

471

# Usage

472

def safe_video_info(video_url):

473

with pytube_error_context("video info extraction"):

474

yt = YouTube(video_url)

475

return {

476

'title': yt.title,

477

'author': yt.author,

478

'length': yt.length,

479

'views': yt.views

480

}

481

482

# Usage

483

try:

484

info = safe_video_info('https://www.youtube.com/watch?v=VIDEO_ID')

485

print(f"Video info: {info}")

486

except PytubeError:

487

print("Failed to get video info due to pytube error")

488

except Exception:

489

print("Failed to get video info due to unexpected error")

490

```

491

492

## Types

493

494

```python { .api }

495

from typing import Union

496

import re

497

498

# Type for regex patterns

499

Pattern = Union[str, re.Pattern]

500

501

# Exception hierarchy summary for type checking

502

VideoAvailabilityError = Union[

503

VideoUnavailable,

504

AgeRestrictedError,

505

LiveStreamError,

506

VideoPrivate,

507

RecordingUnavailable,

508

MembersOnly,

509

VideoRegionBlocked

510

]

511

512

ExtractionError = Union[

513

HTMLParseError,

514

ExtractError,

515

RegexMatchError

516

]

517

518

NetworkError = Union[

519

MaxRetriesExceeded

520

]

521

```