or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

device-shadows.mdexception-handling.mdgreengrass-discovery.mdindex.mdiot-jobs.mdmqtt-client.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Comprehensive exception classes for timeout conditions, operation errors, connection failures, and Greengrass discovery issues. The AWS IoT Python SDK provides specific exceptions for different failure modes, enabling robust error handling and recovery strategies in IoT applications.

3

4

## Capabilities

5

6

### Base Exception Classes

7

8

Foundation exception classes that provide common error handling patterns.

9

10

```python { .api }

11

class operationError(Exception):

12

"""

13

Base class for operation-related errors in AWS IoT operations.

14

Raised when MQTT operations fail due to protocol or client issues.

15

"""

16

17

class operationTimeoutException(Exception):

18

"""

19

Base class for timeout-related errors in AWS IoT operations.

20

Raised when operations exceed configured timeout periods.

21

"""

22

23

class acceptTimeoutException(Exception):

24

"""

25

Raised when socket accept operation times out.

26

Used in low-level connection establishment scenarios.

27

"""

28

```

29

30

### Connection Exceptions

31

32

Exceptions related to MQTT connection establishment and management.

33

34

```python { .api }

35

class connectTimeoutException(operationTimeoutException):

36

"""Raised when MQTT connection attempt times out"""

37

38

class connectError(operationError):

39

"""Raised when MQTT connection fails due to protocol or authentication errors"""

40

41

class disconnectTimeoutException(operationTimeoutException):

42

"""Raised when MQTT disconnection attempt times out"""

43

44

class disconnectError(operationError):

45

"""Raised when MQTT disconnection fails"""

46

```

47

48

### Publish Operation Exceptions

49

50

Exceptions specific to MQTT publish operations and queue management.

51

52

```python { .api }

53

class publishTimeoutException(operationTimeoutException):

54

"""Raised when MQTT publish operation times out (QoS 1)"""

55

56

class publishError(operationError):

57

"""Raised when MQTT publish operation fails"""

58

59

class publishQueueFullException(operationError):

60

"""Raised when offline publish queue is full and configured to reject new messages"""

61

62

class publishQueueDisabledException(operationError):

63

"""Raised when attempting to queue publish messages but queueing is disabled"""

64

```

65

66

### Subscribe Operation Exceptions

67

68

Exceptions for MQTT subscription operations and acknowledgment handling.

69

70

```python { .api }

71

class subscribeTimeoutException(operationTimeoutException):

72

"""Raised when MQTT subscribe operation times out"""

73

74

class subscribeError(operationError):

75

"""Raised when MQTT subscribe operation fails"""

76

77

class subackError(operationError):

78

"""Raised when MQTT SUBACK indicates subscription failure"""

79

80

class subscribeQueueFullException(operationError):

81

"""Raised when offline subscribe queue is full"""

82

83

class subscribeQueueDisabledException(operationError):

84

"""Raised when attempting to queue subscribe operations but queueing is disabled"""

85

```

86

87

### Unsubscribe Operation Exceptions

88

89

Exceptions for MQTT unsubscribe operations.

90

91

```python { .api }

92

class unsubscribeTimeoutException(operationTimeoutException):

93

"""Raised when MQTT unsubscribe operation times out"""

94

95

class unsubscribeError(operationError):

96

"""Raised when MQTT unsubscribe operation fails"""

97

98

class unsubscribeQueueFullException(operationError):

99

"""Raised when offline unsubscribe queue is full"""

100

101

class unsubscribeQueueDisabledException(operationError):

102

"""Raised when attempting to queue unsubscribe operations but queueing is disabled"""

103

```

104

105

### WebSocket Exceptions

106

107

Exceptions specific to WebSocket SigV4 authentication and connection.

108

109

```python { .api }

110

class wssNoKeyInEnvironmentError(Exception):

111

"""Raised when WebSocket SigV4 credentials are missing from environment"""

112

113

class wssHandShakeError(Exception):

114

"""Raised when WebSocket handshake fails during connection establishment"""

115

```

116

117

### Greengrass Discovery Exceptions

118

119

Exceptions for Greengrass core discovery operations.

120

121

```python { .api }

122

class DiscoveryTimeoutException(Exception):

123

"""Raised when Greengrass discovery request times out"""

124

125

class DiscoveryUnauthorizedException(Exception):

126

"""Raised when Greengrass discovery authentication fails"""

127

128

class DiscoveryDataNotFoundException(Exception):

129

"""Raised when no Greengrass discovery data found for the specified thing"""

130

131

class DiscoveryInvalidRequestException(Exception):

132

"""Raised when Greengrass discovery request is malformed or invalid"""

133

134

class DiscoveryThrottlingException(Exception):

135

"""Raised when Greengrass discovery requests are being throttled"""

136

137

class DiscoveryFailure(Exception):

138

"""Raised for general Greengrass discovery service failures"""

139

```

140

141

### General Client Exceptions

142

143

General-purpose client error for miscellaneous failures.

144

145

```python { .api }

146

class ClientError(Exception):

147

"""General client error for SDK-wide failures and misconfigurations"""

148

```

149

150

## Usage Examples

151

152

### Basic Exception Handling

153

154

```python

155

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

156

from AWSIoTPythonSDK.exception.AWSIoTExceptions import (

157

connectTimeoutException,

158

connectError,

159

publishTimeoutException,

160

subscribeTimeoutException

161

)

162

163

# Create and configure client

164

client = AWSIoTPyMQTT.AWSIoTMQTTClient("errorHandlingClient")

165

client.configureEndpoint("endpoint.iot.region.amazonaws.com", 8883)

166

client.configureCredentials("rootCA.crt", "private.key", "certificate.crt")

167

168

# Configure timeouts

169

client.configureConnectDisconnectTimeout(10)

170

client.configureMQTTOperationTimeout(5)

171

172

try:

173

# Attempt connection with timeout handling

174

if not client.connect():

175

raise connectError("Failed to establish MQTT connection")

176

177

print("Connected successfully")

178

179

# Attempt publish with timeout handling

180

if not client.publish("test/topic", "Hello World", 1):

181

raise publishTimeoutException("Publish operation failed")

182

183

print("Message published successfully")

184

185

# Attempt subscribe with timeout handling

186

def messageCallback(client, userdata, message):

187

print(f"Received: {message.payload.decode()}")

188

189

if not client.subscribe("test/response", 1, messageCallback):

190

raise subscribeTimeoutException("Subscribe operation failed")

191

192

print("Subscribed successfully")

193

194

except connectTimeoutException:

195

print("Connection timed out - check network connectivity and endpoint")

196

197

except connectError:

198

print("Connection failed - check credentials and endpoint configuration")

199

200

except publishTimeoutException:

201

print("Publish timed out - message may not have been delivered")

202

203

except subscribeTimeoutException:

204

print("Subscribe timed out - subscription may not be active")

205

206

except Exception as e:

207

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

208

209

finally:

210

try:

211

client.disconnect()

212

except:

213

pass # Ignore disconnect errors in cleanup

214

```

215

216

### Queue Exception Handling

217

218

```python

219

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

220

from AWSIoTPythonSDK.exception.AWSIoTExceptions import (

221

publishQueueFullException,

222

publishQueueDisabledException

223

)

224

225

# Create client with limited queue

226

client = AWSIoTPyMQTT.AWSIoTMQTTClient("queueClient")

227

client.configureEndpoint("endpoint.iot.region.amazonaws.com", 8883)

228

client.configureCredentials("rootCA.crt", "private.key", "certificate.crt")

229

230

# Configure small queue for demonstration

231

client.configureOfflinePublishQueueing(5, AWSIoTPyMQTT.DROP_NEWEST)

232

233

try:

234

client.connect()

235

236

# Simulate offline condition by disconnecting

237

client.disconnect()

238

239

# Attempt to publish while offline

240

for i in range(10): # More messages than queue capacity

241

try:

242

message = f"Offline message {i}"

243

if not client.publish("offline/topic", message, 1):

244

print(f"Message {i} queued for offline delivery")

245

246

except publishQueueFullException:

247

print(f"Queue full - message {i} rejected")

248

# Implement retry logic or alternative handling

249

250

except publishQueueDisabledException:

251

print("Queueing is disabled - reconfigure client for offline operation")

252

break

253

254

except Exception as e:

255

print(f"Queue operation failed: {e}")

256

```

257

258

### Greengrass Discovery Exception Handling

259

260

```python

261

from AWSIoTPythonSDK.core.greengrass.discovery.providers import DiscoveryInfoProvider

262

from AWSIoTPythonSDK.exception.AWSIoTExceptions import (

263

DiscoveryTimeoutException,

264

DiscoveryUnauthorizedException,

265

DiscoveryDataNotFoundException,

266

DiscoveryThrottlingException,

267

DiscoveryFailure

268

)

269

import time

270

271

def robust_discovery(thing_name, max_retries=3):

272

"""Perform Greengrass discovery with comprehensive error handling"""

273

274

discoveryProvider = DiscoveryInfoProvider()

275

discoveryProvider.configureEndpoint("greengrass-ats.iot.region.amazonaws.com")

276

discoveryProvider.configureCredentials("rootCA.crt", "certificate.crt", "private.key")

277

discoveryProvider.configureTimeout(30)

278

279

for attempt in range(max_retries):

280

try:

281

print(f"Discovery attempt {attempt + 1}")

282

283

discoveryInfo = discoveryProvider.discover(thing_name)

284

print("Discovery successful")

285

return discoveryInfo

286

287

except DiscoveryTimeoutException:

288

print("Discovery timed out - check network connectivity")

289

if attempt < max_retries - 1:

290

print("Retrying with longer timeout...")

291

discoveryProvider.configureTimeout(60) # Increase timeout

292

time.sleep(5)

293

294

except DiscoveryUnauthorizedException:

295

print("Discovery authentication failed")

296

print("Check certificate validity and thing permissions")

297

return None # Don't retry auth failures

298

299

except DiscoveryDataNotFoundException:

300

print(f"No discovery data for thing: {thing_name}")

301

print("Ensure thing is associated with a Greengrass group")

302

return None # Don't retry data not found

303

304

except DiscoveryThrottlingException:

305

print("Discovery requests are being throttled")

306

if attempt < max_retries - 1:

307

backoff_time = 2 ** attempt # Exponential backoff

308

print(f"Backing off for {backoff_time} seconds...")

309

time.sleep(backoff_time)

310

311

except DiscoveryFailure as e:

312

print(f"Discovery service failure: {e}")

313

if attempt < max_retries - 1:

314

print("Retrying discovery request...")

315

time.sleep(2)

316

317

except Exception as e:

318

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

319

if attempt < max_retries - 1:

320

time.sleep(2)

321

322

print(f"Discovery failed after {max_retries} attempts")

323

return None

324

325

# Usage

326

discovery_result = robust_discovery("myIoTDevice")

327

if discovery_result:

328

cores = discovery_result.getAllCores()

329

print(f"Found {len(cores)} Greengrass cores")

330

else:

331

print("Discovery failed - falling back to direct AWS IoT connection")

332

```

333

334

### Comprehensive Error Recovery

335

336

```python

337

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

338

from AWSIoTPythonSDK.exception.AWSIoTExceptions import *

339

import time

340

import logging

341

342

# Configure logging

343

logging.basicConfig(level=logging.INFO)

344

logger = logging.getLogger(__name__)

345

346

class RobustIoTClient:

347

"""IoT client with comprehensive error handling and recovery"""

348

349

def __init__(self, client_id, endpoint, port=8883):

350

self.client_id = client_id

351

self.endpoint = endpoint

352

self.port = port

353

self.client = None

354

self.connected = False

355

self.max_retries = 3

356

self.retry_delay = 5

357

358

def configure_credentials(self, ca_path, key_path, cert_path):

359

"""Configure client credentials"""

360

self.ca_path = ca_path

361

self.key_path = key_path

362

self.cert_path = cert_path

363

364

def create_client(self):

365

"""Create and configure MQTT client"""

366

self.client = AWSIoTPyMQTT.AWSIoTMQTTClient(self.client_id)

367

self.client.configureEndpoint(self.endpoint, self.port)

368

self.client.configureCredentials(self.ca_path, self.key_path, self.cert_path)

369

370

# Configure timeouts and reconnection

371

self.client.configureConnectDisconnectTimeout(10)

372

self.client.configureMQTTOperationTimeout(5)

373

self.client.configureAutoReconnectBackoffTime(1, 32, 20)

374

self.client.configureOfflinePublishQueueing(-1) # Infinite queue

375

376

def connect_with_retry(self):

377

"""Connect with automatic retry and error handling"""

378

for attempt in range(self.max_retries):

379

try:

380

logger.info(f"Connection attempt {attempt + 1}")

381

382

if self.client.connect():

383

self.connected = True

384

logger.info("Connected successfully")

385

return True

386

else:

387

raise connectError("Connection returned False")

388

389

except connectTimeoutException:

390

logger.warning(f"Connection timeout on attempt {attempt + 1}")

391

392

except connectError as e:

393

logger.error(f"Connection error: {e}")

394

395

except Exception as e:

396

logger.error(f"Unexpected connection error: {e}")

397

398

if attempt < self.max_retries - 1:

399

logger.info(f"Retrying in {self.retry_delay} seconds...")

400

time.sleep(self.retry_delay)

401

402

logger.error("Failed to connect after all retries")

403

return False

404

405

def publish_with_retry(self, topic, payload, qos=0):

406

"""Publish with error handling and retry logic"""

407

if not self.connected:

408

logger.warning("Not connected - attempting reconnection")

409

if not self.connect_with_retry():

410

return False

411

412

for attempt in range(self.max_retries):

413

try:

414

if self.client.publish(topic, payload, qos):

415

logger.info(f"Published to {topic}")

416

return True

417

else:

418

raise publishError("Publish returned False")

419

420

except publishTimeoutException:

421

logger.warning(f"Publish timeout on attempt {attempt + 1}")

422

423

except publishQueueFullException:

424

logger.warning("Publish queue full - clearing some messages")

425

# Could implement queue management logic here

426

427

except publishError as e:

428

logger.error(f"Publish error: {e}")

429

430

except Exception as e:

431

logger.error(f"Unexpected publish error: {e}")

432

433

if attempt < self.max_retries - 1:

434

time.sleep(1)

435

436

logger.error(f"Failed to publish to {topic} after all retries")

437

return False

438

439

def subscribe_with_retry(self, topic, qos, callback):

440

"""Subscribe with error handling"""

441

if not self.connected:

442

if not self.connect_with_retry():

443

return False

444

445

try:

446

if self.client.subscribe(topic, qos, callback):

447

logger.info(f"Subscribed to {topic}")

448

return True

449

else:

450

raise subscribeError("Subscribe returned False")

451

452

except subscribeTimeoutException:

453

logger.error("Subscribe operation timed out")

454

455

except subackError:

456

logger.error("Subscribe was rejected by broker")

457

458

except subscribeError as e:

459

logger.error(f"Subscribe error: {e}")

460

461

except Exception as e:

462

logger.error(f"Unexpected subscribe error: {e}")

463

464

return False

465

466

def disconnect_safely(self):

467

"""Disconnect with error handling"""

468

if not self.connected:

469

return

470

471

try:

472

self.client.disconnect()

473

self.connected = False

474

logger.info("Disconnected successfully")

475

476

except disconnectTimeoutException:

477

logger.warning("Disconnect timed out")

478

479

except disconnectError as e:

480

logger.error(f"Disconnect error: {e}")

481

482

except Exception as e:

483

logger.error(f"Unexpected disconnect error: {e}")

484

485

# Usage example

486

client = RobustIoTClient("robustClient", "endpoint.iot.region.amazonaws.com")

487

client.configure_credentials("rootCA.crt", "private.key", "certificate.crt")

488

client.create_client()

489

490

if client.connect_with_retry():

491

# Publish with error handling

492

client.publish_with_retry("test/topic", "Hello World", 1)

493

494

# Subscribe with error handling

495

def message_callback(client, userdata, message):

496

print(f"Received: {message.payload.decode()}")

497

498

client.subscribe_with_retry("test/response", 1, message_callback)

499

500

# Keep running

501

try:

502

time.sleep(30)

503

finally:

504

client.disconnect_safely()

505

```

506

507

## Types

508

509

```python { .api }

510

# Exception hierarchy structure

511

Exception

512

├── acceptTimeoutException

513

├── operationError

514

│ ├── connectError

515

│ ├── disconnectError

516

│ ├── publishError

517

│ ├── publishQueueFullException

518

│ ├── publishQueueDisabledException

519

│ ├── subscribeError

520

│ ├── subackError

521

│ ├── subscribeQueueFullException

522

│ ├── subscribeQueueDisabledException

523

│ ├── unsubscribeError

524

│ ├── unsubscribeQueueFullException

525

│ └── unsubscribeQueueDisabledException

526

├── operationTimeoutException

527

│ ├── connectTimeoutException

528

│ ├── disconnectTimeoutException

529

│ ├── publishTimeoutException

530

│ ├── subscribeTimeoutException

531

│ └── unsubscribeTimeoutException

532

├── wssNoKeyInEnvironmentError

533

├── wssHandShakeError

534

├── DiscoveryTimeoutException

535

├── DiscoveryUnauthorizedException

536

├── DiscoveryDataNotFoundException

537

├── DiscoveryInvalidRequestException

538

├── DiscoveryThrottlingException

539

├── DiscoveryFailure

540

└── ClientError

541

542

# Exception handling best practices

543

error_handling_patterns = {

544

"timeout_exceptions": "Retry with backoff, check network connectivity",

545

"auth_exceptions": "Don't retry, check credentials and permissions",

546

"queue_exceptions": "Implement queue management or fallback strategies",

547

"discovery_exceptions": "Use exponential backoff, fallback to direct connection",

548

"general_errors": "Log error details, implement graceful degradation"

549

}

550

```