or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcaching.mderror-handling.mdhttp-client.mdindex.mdproxy-support.mdresponse-handling.mdutilities.md

error-handling.mddocs/

0

# Error Handling

1

2

Comprehensive exception hierarchy for handling HTTP errors, connection failures, authentication issues, and malformed responses. All exceptions derive from HttpLib2Error base class, providing structured error handling for different failure scenarios.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Foundation exception classes that provide the base structure for all httplib2 errors.

9

10

```python { .api }

11

class HttpLib2Error(Exception):

12

"""Base exception for all httplib2 errors."""

13

14

class HttpLib2ErrorWithResponse(HttpLib2Error):

15

"""

16

Exception that includes HTTP response data.

17

18

Attributes:

19

response: HTTP response object containing status and headers

20

content: Response body content

21

"""

22

23

def __init__(self, desc, response, content):

24

"""

25

Initialize with description and response data.

26

27

Args:

28

desc (str): Error description

29

response: HTTP response object

30

content: Response body content

31

"""

32

self.response = response

33

self.content = content

34

```

35

36

### HTTP Error Exceptions

37

38

Exceptions for HTTP-specific errors that include response information.

39

40

```python { .api }

41

class RedirectLimit(HttpLib2ErrorWithResponse):

42

"""

43

Too many redirects followed.

44

Raised when redirect count exceeds configured maximum.

45

"""

46

47

class RedirectMissingLocation(HttpLib2ErrorWithResponse):

48

"""

49

Redirect response missing Location header.

50

Raised when server sends redirect status without Location header.

51

"""

52

53

class FailedToDecompressContent(HttpLib2ErrorWithResponse):

54

"""

55

Content decompression failure.

56

Raised when gzip/deflate decompression fails.

57

"""

58

```

59

60

### Authentication Error Exceptions

61

62

Exceptions for authentication-related failures.

63

64

```python { .api }

65

class UnimplementedDigestAuthOptionError(HttpLib2ErrorWithResponse):

66

"""

67

Unsupported digest authentication option.

68

Raised when server requests unsupported digest auth feature.

69

"""

70

71

class UnimplementedHmacDigestAuthOptionError(HttpLib2ErrorWithResponse):

72

"""

73

Unsupported HMAC digest authentication option.

74

Raised when server requests unsupported HMAC digest auth feature.

75

"""

76

```

77

78

### Protocol Error Exceptions

79

80

Exceptions for protocol-level errors and malformed data.

81

82

```python { .api }

83

class MalformedHeader(HttpLib2Error):

84

"""

85

Malformed HTTP header.

86

Raised when HTTP headers cannot be parsed correctly.

87

"""

88

89

class RelativeURIError(HttpLib2Error):

90

"""

91

Relative URI provided when absolute URI required.

92

Raised when relative URI given to request() method.

93

"""

94

```

95

96

### Network Error Exceptions

97

98

Exceptions for network-level connectivity issues.

99

100

```python { .api }

101

class ServerNotFoundError(HttpLib2Error):

102

"""

103

Server hostname not found.

104

Raised when DNS resolution fails for target hostname.

105

"""

106

107

class ProxiesUnavailableError(HttpLib2Error):

108

"""

109

Proxy support unavailable.

110

Raised when proxy configured but PySocks library not installed.

111

"""

112

```

113

114

### Usage Examples

115

116

#### Basic Error Handling

117

118

```python

119

import httplib2

120

121

h = httplib2.Http()

122

123

try:

124

(resp, content) = h.request("http://example.org/")

125

126

if resp.status >= 400:

127

print(f"HTTP Error: {resp.status} {resp.reason}")

128

else:

129

print("Request successful")

130

131

except httplib2.HttpLib2Error as e:

132

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

133

except Exception as e:

134

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

135

```

136

137

#### Handling Specific Error Types

138

139

```python

140

import httplib2

141

142

h = httplib2.Http()

143

144

try:

145

(resp, content) = h.request("http://example.org/redirect-loop")

146

147

except httplib2.RedirectLimit as e:

148

print(f"Too many redirects: {e}")

149

print(f"Last response status: {e.response.status}")

150

print(f"Last response headers: {dict(e.response)}")

151

152

except httplib2.RedirectMissingLocation as e:

153

print(f"Redirect without location: {e}")

154

print(f"Response status: {e.response.status}")

155

156

except httplib2.ServerNotFoundError as e:

157

print(f"Server not found: {e}")

158

159

except httplib2.HttpLib2Error as e:

160

print(f"Other httplib2 error: {e}")

161

```

162

163

#### Authentication Error Handling

164

165

```python

166

import httplib2

167

168

h = httplib2.Http()

169

h.add_credentials('user', 'pass')

170

171

try:

172

(resp, content) = h.request("https://api.example.com/protected")

173

174

except httplib2.UnimplementedDigestAuthOptionError as e:

175

print(f"Unsupported digest auth option: {e}")

176

print(f"Server challenge: {e.response.get('www-authenticate', '')}")

177

178

except httplib2.UnimplementedHmacDigestAuthOptionError as e:

179

print(f"Unsupported HMAC digest auth option: {e}")

180

181

except httplib2.HttpLib2ErrorWithResponse as e:

182

if e.response.status == 401:

183

print("Authentication failed")

184

elif e.response.status == 403:

185

print("Access forbidden")

186

```

187

188

#### Content Processing Errors

189

190

```python

191

import httplib2

192

193

h = httplib2.Http()

194

195

try:

196

(resp, content) = h.request("http://example.org/compressed-data")

197

198

# Process content

199

text = content.decode('utf-8')

200

201

except httplib2.FailedToDecompressContent as e:

202

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

203

print(f"Content-Encoding: {e.response.get('content-encoding', 'none')}")

204

# Fallback to raw content

205

raw_content = e.content

206

207

except UnicodeDecodeError as e:

208

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

209

# Try different encoding or handle as binary

210

```

211

212

#### Network and Connection Errors

213

214

```python

215

import httplib2

216

import socket

217

218

h = httplib2.Http(timeout=10)

219

220

try:

221

(resp, content) = h.request("http://nonexistent.example.com/")

222

223

except httplib2.ServerNotFoundError as e:

224

print(f"DNS resolution failed: {e}")

225

226

except socket.timeout as e:

227

print(f"Request timed out: {e}")

228

229

except socket.error as e:

230

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

231

232

except httplib2.HttpLib2Error as e:

233

print(f"Other httplib2 error: {e}")

234

```

235

236

#### Proxy Configuration Errors

237

238

```python

239

import httplib2

240

import socks

241

242

try:

243

# Attempt to use proxy without PySocks installed

244

proxy_info = httplib2.ProxyInfo(

245

socks.PROXY_TYPE_HTTP,

246

'proxy.example.com',

247

8080

248

)

249

250

h = httplib2.Http(proxy_info=proxy_info)

251

(resp, content) = h.request("http://example.org/")

252

253

except httplib2.ProxiesUnavailableError as e:

254

print(f"Proxy support unavailable: {e}")

255

print("Install PySocks: pip install PySocks")

256

257

except AttributeError as e:

258

print(f"PySocks not installed: {e}")

259

```

260

261

#### Protocol and Header Errors

262

263

```python

264

import httplib2

265

266

h = httplib2.Http()

267

268

try:

269

# Request with malformed response headers

270

(resp, content) = h.request("http://broken-server.example.com/")

271

272

except httplib2.MalformedHeader as e:

273

print(f"Malformed header: {e}")

274

275

except httplib2.RelativeURIError as e:

276

print(f"Invalid URI: {e}")

277

278

except httplib2.HttpLib2Error as e:

279

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

280

```

281

282

### Error Recovery Strategies

283

284

#### Retry Logic

285

286

```python

287

import httplib2

288

import time

289

290

def robust_request(url, max_retries=3, delay=1):

291

"""Make HTTP request with retry logic."""

292

h = httplib2.Http()

293

294

for attempt in range(max_retries):

295

try:

296

(resp, content) = h.request(url)

297

return (resp, content)

298

299

except httplib2.ServerNotFoundError:

300

# Don't retry DNS failures

301

raise

302

303

except (httplib2.HttpLib2Error, socket.error) as e:

304

if attempt == max_retries - 1:

305

raise

306

print(f"Attempt {attempt + 1} failed: {e}")

307

time.sleep(delay * (2 ** attempt)) # Exponential backoff

308

```

309

310

#### Fallback Handling

311

312

```python

313

import httplib2

314

315

def request_with_fallback(primary_url, fallback_url):

316

"""Try primary URL, fall back to secondary."""

317

h = httplib2.Http()

318

319

try:

320

return h.request(primary_url)

321

322

except httplib2.ServerNotFoundError:

323

print(f"Primary server unavailable, trying fallback")

324

return h.request(fallback_url)

325

326

except httplib2.RedirectLimit:

327

print(f"Too many redirects on primary, trying fallback")

328

return h.request(fallback_url)

329

```

330

331

#### Error Context Preservation

332

333

```python

334

import httplib2

335

336

def detailed_request(url):

337

"""Make request with detailed error information."""

338

h = httplib2.Http()

339

340

try:

341

return h.request(url)

342

343

except httplib2.HttpLib2ErrorWithResponse as e:

344

# Log detailed error information

345

error_info = {

346

'error_type': type(e).__name__,

347

'error_message': str(e),

348

'status_code': getattr(e.response, 'status', None),

349

'response_headers': dict(e.response) if e.response else None,

350

'response_content': e.content[:500] if e.content else None # First 500 bytes

351

}

352

print(f"Request failed with context: {error_info}")

353

raise

354

355

except httplib2.HttpLib2Error as e:

356

error_info = {

357

'error_type': type(e).__name__,

358

'error_message': str(e)

359

}

360

print(f"Request failed: {error_info}")

361

raise

362

```

363

364

### Error Categories

365

366

#### Temporary Errors (Retryable)

367

- Network timeouts

368

- Connection reset

369

- Temporary DNS failures

370

- Server overload (503 Service Unavailable)

371

372

#### Permanent Errors (Non-retryable)

373

- DNS resolution failures (ServerNotFoundError)

374

- Authentication failures (401/403)

375

- Resource not found (404)

376

- Malformed requests (400)

377

378

#### Configuration Errors

379

- Missing proxy support (ProxiesUnavailableError)

380

- Invalid proxy configuration

381

- SSL certificate validation failures

382

- Malformed URLs (RelativeURIError)

383

384

#### Protocol Errors

385

- Malformed headers (MalformedHeader)

386

- Invalid redirects (RedirectMissingLocation)

387

- Content decompression failures (FailedToDecompressContent)

388

- Unsupported authentication methods

389

390

### Best Practices

391

392

1. **Catch Specific Exceptions**: Handle specific error types differently

393

2. **Preserve Error Context**: Include response data when available

394

3. **Implement Retry Logic**: For transient network errors

395

4. **Log Error Details**: Include relevant request/response information

396

5. **Graceful Degradation**: Provide fallback behavior when possible

397

6. **Validate Input**: Check URLs and parameters before making requests

398

7. **Handle Timeouts**: Set appropriate timeout values

399

8. **Monitor Error Patterns**: Track common failure scenarios