or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfig-utils.mdcore-search.mdexceptions.mdindex.md

exceptions.mddocs/

0

# Exception Handling

1

2

Exception classes for handling errors during search operations including rate limiting, timeouts, and general API errors. All DDGS exceptions inherit from the base DDGSException class.

3

4

## Capabilities

5

6

### Base Exception

7

8

Base exception class that all DDGS-specific exceptions inherit from.

9

10

```python { .api }

11

class DDGSException(Exception):

12

"""

13

Base exception class for all ddgs-related errors.

14

15

This is the parent class for all exceptions raised by the DDGS library.

16

Catch this exception to handle any DDGS-related error generically.

17

"""

18

```

19

20

### Rate Limit Exception

21

22

Raised when search services return rate limit errors, indicating too many requests have been made in a short time period.

23

24

```python { .api }

25

class RatelimitException(DDGSException):

26

"""

27

Raised when rate limit is exceeded during API requests.

28

29

This exception is thrown when search backends indicate that

30

the request rate limit has been exceeded. The calling code

31

should implement backoff strategies when catching this exception.

32

"""

33

```

34

35

### Timeout Exception

36

37

Raised when search requests exceed the configured timeout period.

38

39

```python { .api }

40

class TimeoutException(DDGSException):

41

"""

42

Raised when API requests timeout.

43

44

This exception is thrown when search operations take longer

45

than the configured timeout value. Consider increasing the

46

timeout value or implementing retry logic.

47

"""

48

```

49

50

## Usage Examples

51

52

### Basic Exception Handling

53

54

```python

55

from ddgs import DDGS, DDGSException

56

57

try:

58

with DDGS() as ddgs:

59

results = ddgs.text("search query")

60

print(f"Found {len(results)} results")

61

except DDGSException as e:

62

print(f"Search failed: {e}")

63

```

64

65

### Specific Exception Handling

66

67

```python

68

from ddgs import DDGS, DDGSException, RatelimitException, TimeoutException

69

import time

70

71

def robust_search(query, max_retries=3, backoff_factor=2):

72

"""Perform search with retry logic for common exceptions."""

73

74

for attempt in range(max_retries):

75

try:

76

with DDGS(timeout=10) as ddgs:

77

return ddgs.text(query, max_results=20)

78

79

except RatelimitException:

80

if attempt < max_retries - 1:

81

wait_time = backoff_factor ** attempt

82

print(f"Rate limited. Waiting {wait_time} seconds before retry...")

83

time.sleep(wait_time)

84

continue

85

else:

86

print("Rate limit exceeded. Max retries reached.")

87

raise

88

89

except TimeoutException:

90

if attempt < max_retries - 1:

91

print(f"Request timed out. Retrying attempt {attempt + 2}...")

92

continue

93

else:

94

print("Request timed out. Max retries reached.")

95

raise

96

97

except DDGSException as e:

98

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

99

raise

100

101

# Usage

102

try:

103

results = robust_search("python programming")

104

print(f"Successfully retrieved {len(results)} results")

105

except DDGSException as e:

106

print(f"All retry attempts failed: {e}")

107

```

108

109

### Exception Handling with Different Search Types

110

111

```python

112

from ddgs import DDGS, DDGSException, RatelimitException, TimeoutException

113

114

def safe_multi_search(query):

115

"""Perform multiple search types with proper exception handling."""

116

117

results = {

118

'text': [],

119

'images': [],

120

'news': [],

121

'videos': [],

122

'books': []

123

}

124

125

search_methods = [

126

('text', lambda ddgs: ddgs.text(query, max_results=10)),

127

('images', lambda ddgs: ddgs.images(query, max_results=5)),

128

('news', lambda ddgs: ddgs.news(query, max_results=5)),

129

('videos', lambda ddgs: ddgs.videos(query, max_results=5)),

130

('books', lambda ddgs: ddgs.books(query, max_results=5))

131

]

132

133

with DDGS(timeout=15) as ddgs:

134

for search_type, search_func in search_methods:

135

try:

136

results[search_type] = search_func(ddgs)

137

print(f"{search_type.title()} search: {len(results[search_type])} results")

138

139

except RatelimitException:

140

print(f"{search_type.title()} search rate limited, skipping...")

141

continue

142

143

except TimeoutException:

144

print(f"{search_type.title()} search timed out, skipping...")

145

continue

146

147

except DDGSException as e:

148

print(f"{search_type.title()} search failed: {e}")

149

continue

150

151

return results

152

153

# Usage

154

try:

155

all_results = safe_multi_search("artificial intelligence")

156

total_results = sum(len(results) for results in all_results.values())

157

print(f"Total results across all search types: {total_results}")

158

except Exception as e:

159

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

160

```

161

162

### Configuration-Based Exception Handling

163

164

```python

165

from ddgs import DDGS, DDGSException, RatelimitException, TimeoutException

166

167

class RobustDDGS:

168

"""Wrapper class with built-in exception handling and retry logic."""

169

170

def __init__(self, timeout=10, max_retries=3, backoff_factor=1.5):

171

self.timeout = timeout

172

self.max_retries = max_retries

173

self.backoff_factor = backoff_factor

174

175

def _execute_with_retry(self, search_func):

176

"""Execute search function with retry logic."""

177

last_exception = None

178

179

for attempt in range(self.max_retries):

180

try:

181

with DDGS(timeout=self.timeout) as ddgs:

182

return search_func(ddgs)

183

184

except RatelimitException as e:

185

last_exception = e

186

if attempt < self.max_retries - 1:

187

wait_time = self.backoff_factor ** attempt

188

time.sleep(wait_time)

189

continue

190

191

except TimeoutException as e:

192

last_exception = e

193

if attempt < self.max_retries - 1:

194

continue

195

196

except DDGSException as e:

197

# Don't retry for general DDGS exceptions

198

raise e

199

200

# If we get here, all retries failed

201

raise last_exception

202

203

def text(self, query, **kwargs):

204

"""Text search with automatic retry."""

205

return self._execute_with_retry(

206

lambda ddgs: ddgs.text(query, **kwargs)

207

)

208

209

def images(self, query, **kwargs):

210

"""Image search with automatic retry."""

211

return self._execute_with_retry(

212

lambda ddgs: ddgs.images(query, **kwargs)

213

)

214

215

# Similar methods for news, videos, books...

216

217

# Usage

218

robust_ddgs = RobustDDGS(timeout=15, max_retries=5)

219

220

try:

221

results = robust_ddgs.text("machine learning", max_results=50)

222

print(f"Retrieved {len(results)} results successfully")

223

except DDGSException as e:

224

print(f"Search failed after all retries: {e}")

225

```

226

227

## Best Practices

228

229

1. **Always use specific exception handling** - Catch `RatelimitException` and `TimeoutException` separately when you need different handling logic.

230

231

2. **Implement backoff strategies** - When catching `RatelimitException`, use exponential backoff before retrying.

232

233

3. **Set appropriate timeouts** - Balance between allowing enough time for searches and not hanging indefinitely.

234

235

4. **Use context managers** - Always use `with DDGS() as ddgs:` to ensure proper resource cleanup.

236

237

5. **Log exceptions for debugging** - Include exception details in logs to help diagnose issues.

238

239

6. **Graceful degradation** - Continue with available results even if some search types fail.

240

241

## Common Error Scenarios

242

243

- **Rate Limiting**: Occurs with high-frequency searches. Implement delays between requests.

244

- **Network Timeouts**: Common with slow internet or overloaded servers. Increase timeout values or retry.

245

- **Service Unavailability**: Individual search backends may be temporarily unavailable. Use "auto" backend for fallback.

246

- **Invalid Parameters**: Check query strings and parameter values before making requests.