or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

administrative-operations.mdclient-management.mdconstants-enums.mdexception-handling.mdindex.mdmessage-operations.mdmessage-types.mdsession-management.md

exception-handling.mddocs/

0

# Exception Handling

1

2

Comprehensive exception hierarchy for handling Service Bus errors including connection issues, authentication failures, message processing errors, and service-side exceptions.

3

4

## Capabilities

5

6

### Base Exception

7

8

Root exception class for all Service Bus-specific errors.

9

10

```python { .api }

11

class ServiceBusError(AzureError):

12

"""

13

Base exception for all Service Bus errors.

14

15

Provides common error handling for all Service Bus operations and includes

16

retry information and error context.

17

"""

18

def __init__(

19

self,

20

message: Optional[Union[str, bytes]],

21

*args,

22

**kwargs

23

) -> None:

24

"""

25

Initialize ServiceBusError.

26

27

Parameters:

28

- message: Error message (string or bytes)

29

- retryable: Whether the operation can be retried (keyword arg)

30

- shutdown_handler: Whether to shutdown handler on error (keyword arg)

31

- condition: AMQP error condition (keyword arg)

32

- status_code: HTTP status code if applicable (keyword arg)

33

"""

34

35

@property

36

def retryable(self) -> bool:

37

"""Whether this error indicates a retryable condition."""

38

39

@property

40

def shutdown_handler(self) -> bool:

41

"""Whether the handler should be shutdown due to this error."""

42

43

@property

44

def condition(self) -> Optional[str]:

45

"""AMQP error condition if available."""

46

47

@property

48

def status_code(self) -> Optional[int]:

49

"""HTTP status code if applicable."""

50

```

51

52

#### Usage Example

53

54

```python

55

from azure.servicebus import ServiceBusClient

56

from azure.servicebus.exceptions import ServiceBusError

57

58

client = ServiceBusClient.from_connection_string("your_connection_string")

59

60

try:

61

with client.get_queue_sender("my-queue") as sender:

62

sender.send_messages(ServiceBusMessage("Hello"))

63

64

except ServiceBusError as e:

65

print(f"Service Bus error: {e}")

66

print(f"Retryable: {e.retryable}")

67

print(f"Status code: {e.status_code}")

68

print(f"Condition: {e.condition}")

69

70

if e.retryable:

71

# Implement retry logic

72

retry_operation()

73

else:

74

# Handle non-retryable error

75

handle_permanent_failure()

76

```

77

78

### Connection and Communication Errors

79

80

Exceptions related to network connectivity and communication with Service Bus.

81

82

```python { .api }

83

class ServiceBusConnectionError(ServiceBusError):

84

"""

85

An error occurred in the connection to Service Bus.

86

87

This is a retryable error that typically indicates network issues

88

or temporary service unavailability.

89

"""

90

91

class ServiceBusCommunicationError(ServiceBusError):

92

"""

93

A general communications error when interacting with Service Bus.

94

95

Client cannot establish or maintain a connection to Service Bus.

96

Check network connectivity, firewall settings, and Service Bus availability.

97

"""

98

```

99

100

#### Usage Example

101

102

```python

103

from azure.servicebus import ServiceBusClient

104

from azure.servicebus.exceptions import (

105

ServiceBusConnectionError,

106

ServiceBusCommunicationError

107

)

108

import time

109

110

client = ServiceBusClient.from_connection_string("your_connection_string")

111

112

def send_with_retry(message, max_retries=3):

113

for attempt in range(max_retries):

114

try:

115

with client.get_queue_sender("my-queue") as sender:

116

sender.send_messages(message)

117

return # Success

118

119

except ServiceBusConnectionError as e:

120

print(f"Connection error (attempt {attempt + 1}): {e}")

121

if attempt < max_retries - 1:

122

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

123

else:

124

raise

125

126

except ServiceBusCommunicationError as e:

127

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

128

print("Check network connectivity and firewall settings")

129

raise

130

```

131

132

### Authentication and Authorization Errors

133

134

Exceptions related to credential validation and access permissions.

135

136

```python { .api }

137

class ServiceBusAuthenticationError(ServiceBusError):

138

"""

139

An error occurred when authenticating the connection.

140

141

Credential validation failed. Check that credentials are valid

142

and not expired.

143

"""

144

145

class ServiceBusAuthorizationError(ServiceBusError):

146

"""

147

An error occurred when authorizing the connection.

148

149

Access to the requested resource is denied. Check that the credential

150

has appropriate permissions for the operation.

151

"""

152

```

153

154

#### Usage Example

155

156

```python

157

from azure.servicebus import ServiceBusClient

158

from azure.servicebus.exceptions import (

159

ServiceBusAuthenticationError,

160

ServiceBusAuthorizationError

161

)

162

163

try:

164

client = ServiceBusClient.from_connection_string("invalid_connection_string")

165

with client.get_queue_sender("my-queue") as sender:

166

sender.send_messages(ServiceBusMessage("Hello"))

167

168

except ServiceBusAuthenticationError as e:

169

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

170

print("Check connection string and credentials")

171

172

except ServiceBusAuthorizationError as e:

173

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

174

print("Check that the credential has Send permissions for the queue")

175

```

176

177

### Message Processing Errors

178

179

Exceptions related to message handling and settlement operations.

180

181

```python { .api }

182

class MessageAlreadySettled(ValueError):

183

"""

184

Failed to settle the message because it was already settled.

185

186

An attempt was made to complete, abandon, defer, or dead-letter a message

187

that has already been settled. This is not a retryable error.

188

"""

189

190

class MessageLockLostError(ServiceBusError):

191

"""

192

The lock on the message has expired.

193

194

The message lock has expired and the message is no longer exclusively

195

locked to this receiver. The message will become available to other

196

receivers. This is not a retryable error for the same message instance.

197

"""

198

199

class MessageNotFoundError(ServiceBusError):

200

"""

201

The requested message was not found.

202

203

Attempt to receive a message with a specific sequence number failed

204

because the message no longer exists or has been processed.

205

"""

206

207

class MessageSizeExceededError(ServiceBusError, ValueError):

208

"""

209

Message content is larger than the Service Bus frame size limit.

210

211

The message exceeds the maximum allowed size. Reduce message size

212

or split into multiple messages.

213

"""

214

```

215

216

#### Usage Example

217

218

```python

219

from azure.servicebus import ServiceBusClient, ServiceBusMessage

220

from azure.servicebus.exceptions import (

221

MessageAlreadySettled,

222

MessageLockLostError,

223

MessageNotFoundError,

224

MessageSizeExceededError

225

)

226

import time

227

228

client = ServiceBusClient.from_connection_string("your_connection_string")

229

230

def process_messages_safely():

231

with client.get_queue_receiver("my-queue") as receiver:

232

messages = receiver.receive_messages(max_message_count=10)

233

234

for message in messages:

235

try:

236

# Simulate long processing

237

result = process_message(message)

238

239

# Attempt to complete the message

240

receiver.complete_message(message)

241

print(f"Successfully processed: {result}")

242

243

except MessageAlreadySettled:

244

print("Message was already settled by another process")

245

continue

246

247

except MessageLockLostError:

248

print(f"Message lock expired during processing: {message.sequence_number}")

249

# Message will be available for other receivers

250

continue

251

252

except Exception as processing_error:

253

print(f"Error processing message: {processing_error}")

254

try:

255

receiver.abandon_message(message)

256

except MessageAlreadySettled:

257

print("Message was already settled during error handling")

258

259

def send_large_message():

260

try:

261

# Create a very large message

262

large_content = "x" * (1024 * 1024 * 2) # 2MB message

263

message = ServiceBusMessage(large_content)

264

265

with client.get_queue_sender("my-queue") as sender:

266

sender.send_messages(message)

267

268

except MessageSizeExceededError as e:

269

print(f"Message too large: {e}")

270

print("Consider using message batching or splitting the message")

271

```

272

273

### Session-Related Errors

274

275

Exceptions specific to session-enabled messaging scenarios.

276

277

```python { .api }

278

class SessionLockLostError(ServiceBusError):

279

"""

280

The lock on the session has expired.

281

282

All unsettled messages that have been received can no longer be settled.

283

The session must be re-acquired to continue processing.

284

"""

285

286

class SessionCannotBeLockedError(ServiceBusError):

287

"""

288

The requested session cannot be locked.

289

290

The session is currently locked by another client, does not exist,

291

or the session ID is invalid.

292

"""

293

```

294

295

#### Usage Example

296

297

```python

298

from azure.servicebus import ServiceBusClient, NEXT_AVAILABLE_SESSION

299

from azure.servicebus.exceptions import (

300

SessionLockLostError,

301

SessionCannotBeLockedError

302

)

303

304

client = ServiceBusClient.from_connection_string("your_connection_string")

305

306

def process_session_safely(session_id):

307

try:

308

with client.get_queue_receiver("my-session-queue", session_id=session_id) as receiver:

309

session = receiver.session

310

311

messages = receiver.receive_messages(max_message_count=10)

312

for message in messages:

313

try:

314

# Process message with session state

315

process_with_session_state(message, session)

316

receiver.complete_message(message)

317

318

except SessionLockLostError:

319

print(f"Session {session_id} lock expired")

320

break # Exit and let session be re-acquired

321

322

except SessionCannotBeLockedError:

323

print(f"Cannot lock session {session_id} - trying next available")

324

325

# Try to get any available session instead

326

try:

327

with client.get_queue_receiver("my-session-queue", session_id=NEXT_AVAILABLE_SESSION) as receiver:

328

if receiver.session:

329

print(f"Got available session: {receiver.session.session_id}")

330

# Process this session instead

331

else:

332

print("No sessions available")

333

except SessionCannotBeLockedError:

334

print("No sessions available at all")

335

```

336

337

### Entity Management Errors

338

339

Exceptions related to Service Bus entity operations.

340

341

```python { .api }

342

class MessagingEntityNotFoundError(ServiceBusError):

343

"""

344

A Service Bus resource cannot be found.

345

346

The entity (queue, topic, subscription, or rule) associated with the

347

operation does not exist or has been deleted.

348

"""

349

350

class MessagingEntityDisabledError(ServiceBusError):

351

"""

352

The messaging entity is disabled.

353

354

The entity exists but is disabled and cannot process messages.

355

Enable the entity using the Azure portal or management API.

356

"""

357

358

class MessagingEntityAlreadyExistsError(ServiceBusError):

359

"""

360

An entity with the same name already exists.

361

362

Cannot create an entity because one with the same name already exists

363

in the namespace.

364

"""

365

```

366

367

#### Usage Example

368

369

```python

370

from azure.servicebus import ServiceBusClient, ServiceBusMessage

371

from azure.servicebus.exceptions import (

372

MessagingEntityNotFoundError,

373

MessagingEntityDisabledError

374

)

375

from azure.servicebus.management import ServiceBusAdministrationClient

376

from azure.servicebus.exceptions import MessagingEntityAlreadyExistsError

377

378

client = ServiceBusClient.from_connection_string("your_connection_string")

379

admin_client = ServiceBusAdministrationClient.from_connection_string("your_connection_string")

380

381

def safe_queue_operations(queue_name):

382

try:

383

# Try to send to queue

384

with client.get_queue_sender(queue_name) as sender:

385

sender.send_messages(ServiceBusMessage("Hello"))

386

387

except MessagingEntityNotFoundError:

388

print(f"Queue {queue_name} does not exist - creating it")

389

try:

390

admin_client.create_queue(queue_name)

391

print(f"Created queue {queue_name}")

392

# Retry the send operation

393

with client.get_queue_sender(queue_name) as sender:

394

sender.send_messages(ServiceBusMessage("Hello"))

395

except MessagingEntityAlreadyExistsError:

396

print(f"Queue {queue_name} was created by another process")

397

398

except MessagingEntityDisabledError:

399

print(f"Queue {queue_name} is disabled - check Azure portal")

400

```

401

402

### Service-Level Errors

403

404

Exceptions related to Service Bus service conditions and limits.

405

406

```python { .api }

407

class ServiceBusQuotaExceededError(ServiceBusError):

408

"""

409

A Service Bus resource quota has been exceeded.

410

411

The messaging entity has reached its maximum size, or the maximum

412

number of connections to a namespace has been exceeded.

413

"""

414

415

class ServiceBusServerBusyError(ServiceBusError):

416

"""

417

The Service Bus service reports that it is busy.

418

419

The service cannot process the request at this time. Client should

420

wait and retry the operation after a delay.

421

"""

422

423

class OperationTimeoutError(ServiceBusError):

424

"""

425

The operation timed out.

426

427

The operation did not complete within the specified timeout period.

428

This is typically a retryable error.

429

"""

430

```

431

432

#### Usage Example

433

434

```python

435

from azure.servicebus import ServiceBusClient

436

from azure.servicebus.exceptions import (

437

ServiceBusQuotaExceededError,

438

ServiceBusServerBusyError,

439

OperationTimeoutError

440

)

441

import time

442

import random

443

444

client = ServiceBusClient.from_connection_string("your_connection_string")

445

446

def send_with_service_error_handling(message):

447

max_retries = 5

448

base_delay = 1

449

450

for attempt in range(max_retries):

451

try:

452

with client.get_queue_sender("my-queue", timeout=30) as sender:

453

sender.send_messages(message)

454

return # Success

455

456

except ServiceBusQuotaExceededError as e:

457

print(f"Quota exceeded: {e}")

458

print("Cannot send more messages - queue/namespace is full")

459

raise # Don't retry quota errors

460

461

except ServiceBusServerBusyError as e:

462

print(f"Service busy (attempt {attempt + 1}): {e}")

463

if attempt < max_retries - 1:

464

# Exponential backoff with jitter

465

delay = base_delay * (2 ** attempt) + random.uniform(0, 1)

466

time.sleep(delay)

467

else:

468

raise

469

470

except OperationTimeoutError as e:

471

print(f"Operation timeout (attempt {attempt + 1}): {e}")

472

if attempt < max_retries - 1:

473

time.sleep(base_delay * (attempt + 1))

474

else:

475

raise

476

```

477

478

### Lock Renewal Errors

479

480

Exceptions related to automatic lock renewal operations.

481

482

```python { .api }

483

class AutoLockRenewFailed(ServiceBusError):

484

"""

485

An attempt to renew a lock on a message or session in the background has failed.

486

487

The auto-renewal process encountered an error. Check the specific error

488

details to determine if manual intervention is required.

489

"""

490

491

class AutoLockRenewTimeout(ServiceBusError):

492

"""

493

The time allocated to renew the message or session lock has elapsed.

494

495

The maximum renewal duration has been reached and no further renewal

496

attempts will be made.

497

"""

498

```

499

500

#### Usage Example

501

502

```python

503

from azure.servicebus import ServiceBusClient, AutoLockRenewer

504

from azure.servicebus.exceptions import (

505

AutoLockRenewFailed,

506

AutoLockRenewTimeout

507

)

508

509

def handle_auto_renew_errors(renewable, error):

510

"""Callback for auto-renewal failures."""

511

if isinstance(error, AutoLockRenewFailed):

512

print(f"Auto-renewal failed for {renewable}: {error}")

513

# Log the error and potentially implement fallback logic

514

515

elif isinstance(error, AutoLockRenewTimeout):

516

print(f"Auto-renewal timeout for {renewable}: {error}")

517

# The renewal period has ended - message/session lock will expire

518

519

else:

520

print(f"Unexpected auto-renewal error: {error}")

521

522

client = ServiceBusClient.from_connection_string("your_connection_string")

523

auto_renewer = AutoLockRenewer(

524

max_lock_renewal_duration=300, # 5 minutes

525

on_lock_renew_failure=handle_auto_renew_errors

526

)

527

528

try:

529

with client.get_queue_receiver("my-queue") as receiver:

530

messages = receiver.receive_messages(max_message_count=5)

531

532

for message in messages:

533

# Register for auto-renewal

534

auto_renewer.register(message, timeout=300)

535

536

try:

537

# Long-running processing

538

result = long_running_process(message)

539

receiver.complete_message(message)

540

541

except Exception as e:

542

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

543

receiver.abandon_message(message)

544

545

finally:

546

auto_renewer.close()

547

```

548

549

## Error Handling Best Practices

550

551

### Comprehensive Error Handling Pattern

552

553

```python

554

from azure.servicebus import ServiceBusClient, ServiceBusMessage, AutoLockRenewer

555

from azure.servicebus.exceptions import *

556

from azure.servicebus.management import ServiceBusAdministrationClient

557

import logging

558

import time

559

560

logging.basicConfig(level=logging.INFO)

561

logger = logging.getLogger(__name__)

562

563

def robust_message_processing():

564

client = ServiceBusClient.from_connection_string("your_connection_string")

565

566

try:

567

with client.get_queue_receiver("my-queue") as receiver:

568

while True:

569

try:

570

messages = receiver.receive_messages(

571

max_message_count=10,

572

max_wait_time=30

573

)

574

575

if not messages:

576

logger.info("No messages received")

577

continue

578

579

for message in messages:

580

try:

581

# Process individual message

582

process_single_message(receiver, message)

583

584

except MessageAlreadySettled:

585

logger.warning(f"Message {message.sequence_number} already settled")

586

continue

587

588

except MessageLockLostError:

589

logger.warning(f"Lock lost for message {message.sequence_number}")

590

continue

591

592

except OperationTimeoutError:

593

logger.info("Receive operation timed out - continuing")

594

continue

595

596

except ServiceBusServerBusyError:

597

logger.warning("Service busy - backing off")

598

time.sleep(30)

599

continue

600

601

except MessagingEntityNotFoundError:

602

logger.error("Queue not found - exiting")

603

break

604

605

except (ServiceBusConnectionError, ServiceBusCommunicationError) as e:

606

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

607

time.sleep(5)

608

continue

609

610

except ServiceBusAuthenticationError:

611

logger.error("Authentication failed - check credentials")

612

raise

613

614

except ServiceBusAuthorizationError:

615

logger.error("Authorization failed - check permissions")

616

raise

617

618

finally:

619

client.close()

620

621

def process_single_message(receiver, message):

622

"""Process a single message with proper error handling."""

623

try:

624

# Your message processing logic here

625

result = your_message_processor(message)

626

receiver.complete_message(message)

627

logger.info(f"Successfully processed message {message.sequence_number}")

628

629

except Exception as processing_error:

630

logger.error(f"Error processing message {message.sequence_number}: {processing_error}")

631

632

# Decide whether to abandon or dead-letter based on error type and delivery count

633

if message.delivery_count and message.delivery_count >= 3:

634

receiver.dead_letter_message(

635

message,

636

reason="ProcessingFailed",

637

error_description=str(processing_error)

638

)

639

logger.warning(f"Dead-lettered message {message.sequence_number} after {message.delivery_count} attempts")

640

else:

641

receiver.abandon_message(message)

642

logger.info(f"Abandoned message {message.sequence_number} for retry")

643

```

644

645

This comprehensive error handling pattern demonstrates how to handle all major exception types that can occur during Service Bus operations, with appropriate retry logic and logging.