or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batches.mdbeta.mdclient-initialization.mderrors.mdindex.mdmessages.mdmodels.mdplatform-clients.mdstreaming.mdtools-builtin.mdtools-decorators.mdtools-function.mdtools-memory.mdtools-runners.mdtools.mdtypes.md

errors.mddocs/

0

# Error Handling

1

2

Comprehensive exception handling for the Anthropic Python SDK. All exceptions inherit from `AnthropicError` and provide detailed error information including HTTP status codes, request IDs, and response bodies.

3

4

## Exception Hierarchy

5

6

```

7

AnthropicError (Base exception for all SDK errors)

8

├── APIError (Base for API-related errors)

9

│ ├── APIConnectionError (Connection failures)

10

│ │ └── APITimeoutError (Request timeouts)

11

│ ├── APIResponseValidationError (Response validation failures)

12

│ └── APIStatusError (HTTP status errors)

13

│ ├── BadRequestError (400)

14

│ ├── AuthenticationError (401)

15

│ ├── PermissionDeniedError (403)

16

│ ├── NotFoundError (404)

17

│ ├── ConflictError (409)

18

│ ├── RequestTooLargeError (413)

19

│ ├── UnprocessableEntityError (422)

20

│ ├── RateLimitError (429)

21

│ ├── ServiceUnavailableError (503)

22

│ ├── DeadlineExceededError (504)

23

│ ├── OverloadedError (529)

24

│ └── InternalServerError (5xx)

25

```

26

27

## Base Exceptions

28

29

### AnthropicError

30

31

```python { .api }

32

class AnthropicError(Exception):

33

"""

34

Base exception for all Anthropic SDK errors.

35

36

All other exceptions inherit from this base class.

37

"""

38

```

39

40

**Usage:**

41

42

```python

43

import anthropic

44

from anthropic import AnthropicError

45

46

client = anthropic.Anthropic(api_key="your-api-key")

47

48

try:

49

message = client.messages.create(

50

model="claude-3-5-sonnet-20241022",

51

max_tokens=1024,

52

messages=[{"role": "user", "content": "Hello!"}]

53

)

54

except AnthropicError as e:

55

# Catches all SDK exceptions

56

print(f"An error occurred: {e}")

57

```

58

59

### APIError

60

61

```python { .api }

62

class APIError(AnthropicError):

63

"""

64

Base exception for API-related errors.

65

66

Contains request and response information.

67

"""

68

69

message: str

70

"""Error message describing what went wrong"""

71

72

request: httpx.Request

73

"""The HTTP request object that triggered the error"""

74

75

body: object | None

76

"""

77

The API response body.

78

79

If the API responded with valid JSON, this will be the decoded result.

80

If it isn't valid JSON, this will be the raw response text.

81

If there was no response, this will be None.

82

"""

83

84

def __init__(

85

self,

86

message: str,

87

request: httpx.Request,

88

*,

89

body: object | None

90

) -> None: ...

91

```

92

93

**Usage:**

94

95

```python

96

import anthropic

97

from anthropic import APIError

98

99

client = anthropic.Anthropic(api_key="your-api-key")

100

101

try:

102

message = client.messages.create(

103

model="claude-3-5-sonnet-20241022",

104

max_tokens=1024,

105

messages=[{"role": "user", "content": "Hello!"}]

106

)

107

except APIError as e:

108

print(f"API Error: {e.message}")

109

print(f"Request URL: {e.request.url}")

110

if e.body:

111

print(f"Response body: {e.body}")

112

```

113

114

## HTTP Status Errors

115

116

### APIStatusError

117

118

```python { .api }

119

class APIStatusError(APIError):

120

"""

121

Base exception for HTTP status errors (4xx and 5xx responses).

122

123

Raised when the API returns an error status code.

124

"""

125

126

response: httpx.Response

127

"""The HTTP response object"""

128

129

status_code: int

130

"""HTTP status code (e.g., 400, 401, 429, 500)"""

131

132

request_id: str | None

133

"""

134

Request ID from response headers for debugging.

135

136

Available in the 'request-id' header. Useful when contacting support.

137

"""

138

139

def __init__(

140

self,

141

message: str,

142

*,

143

response: httpx.Response,

144

body: object | None

145

) -> None: ...

146

```

147

148

**Usage:**

149

150

```python

151

import anthropic

152

from anthropic import APIStatusError

153

154

client = anthropic.Anthropic(api_key="your-api-key")

155

156

try:

157

message = client.messages.create(

158

model="claude-3-5-sonnet-20241022",

159

max_tokens=1024,

160

messages=[{"role": "user", "content": "Hello!"}]

161

)

162

except APIStatusError as e:

163

print(f"HTTP {e.status_code}: {e.message}")

164

print(f"Request ID: {e.request_id}")

165

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

166

```

167

168

### BadRequestError (400)

169

170

```python { .api }

171

class BadRequestError(APIStatusError):

172

"""

173

400 Bad Request error.

174

175

Raised when the request is malformed or contains invalid parameters.

176

"""

177

178

status_code: Literal[400] = 400

179

```

180

181

**Common Causes:**

182

183

- Invalid JSON in request body

184

- Missing required parameters

185

- Invalid parameter values

186

- Malformed message format

187

188

**Example:**

189

190

```python

191

import anthropic

192

from anthropic import BadRequestError

193

194

client = anthropic.Anthropic(api_key="your-api-key")

195

196

try:

197

# Missing required 'messages' parameter

198

message = client.messages.create(

199

model="claude-3-5-sonnet-20241022",

200

max_tokens=1024

201

)

202

except BadRequestError as e:

203

print(f"Bad Request: {e.message}")

204

print(f"Request ID: {e.request_id}")

205

# Fix the request based on error message

206

if e.body:

207

print(f"Details: {e.body}")

208

```

209

210

### AuthenticationError (401)

211

212

```python { .api }

213

class AuthenticationError(APIStatusError):

214

"""

215

401 Unauthorized error.

216

217

Raised when authentication fails due to invalid or missing API key.

218

"""

219

220

status_code: Literal[401] = 401

221

```

222

223

**Common Causes:**

224

225

- Invalid API key

226

- Missing API key

227

- Expired API key

228

- API key without proper permissions

229

230

**Example:**

231

232

```python

233

import anthropic

234

from anthropic import AuthenticationError

235

236

try:

237

client = anthropic.Anthropic(api_key="invalid-key")

238

message = client.messages.create(

239

model="claude-3-5-sonnet-20241022",

240

max_tokens=1024,

241

messages=[{"role": "user", "content": "Hello!"}]

242

)

243

except AuthenticationError as e:

244

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

245

print(f"Request ID: {e.request_id}")

246

print("Please check your API key")

247

# Prompt user to enter valid API key

248

```

249

250

### PermissionDeniedError (403)

251

252

```python { .api }

253

class PermissionDeniedError(APIStatusError):

254

"""

255

403 Forbidden error.

256

257

Raised when the API key doesn't have permission for the requested resource.

258

"""

259

260

status_code: Literal[403] = 403

261

```

262

263

**Common Causes:**

264

265

- Accessing resources not available to your account

266

- Using features not included in your plan

267

- Attempting operations without proper permissions

268

269

**Example:**

270

271

```python

272

import anthropic

273

from anthropic import PermissionDeniedError

274

275

client = anthropic.Anthropic(api_key="your-api-key")

276

277

try:

278

# Attempting to use a beta feature without access

279

message = client.beta.messages.create(

280

model="claude-3-5-sonnet-20241022",

281

max_tokens=1024,

282

messages=[{"role": "user", "content": "Hello!"}],

283

betas=["restricted-beta-feature"]

284

)

285

except PermissionDeniedError as e:

286

print(f"Permission denied: {e.message}")

287

print(f"Request ID: {e.request_id}")

288

print("This feature may not be available for your account")

289

```

290

291

### NotFoundError (404)

292

293

```python { .api }

294

class NotFoundError(APIStatusError):

295

"""

296

404 Not Found error.

297

298

Raised when the requested resource doesn't exist.

299

"""

300

301

status_code: Literal[404] = 404

302

```

303

304

**Common Causes:**

305

306

- Invalid model ID

307

- Non-existent resource ID

308

- Incorrect endpoint URL

309

310

**Example:**

311

312

```python

313

import anthropic

314

from anthropic import NotFoundError

315

316

client = anthropic.Anthropic(api_key="your-api-key")

317

318

try:

319

# Using invalid model ID

320

message = client.messages.create(

321

model="non-existent-model",

322

max_tokens=1024,

323

messages=[{"role": "user", "content": "Hello!"}]

324

)

325

except NotFoundError as e:

326

print(f"Resource not found: {e.message}")

327

print(f"Request ID: {e.request_id}")

328

329

# Try with a valid model

330

message = client.messages.create(

331

model="claude-3-5-sonnet-20241022",

332

max_tokens=1024,

333

messages=[{"role": "user", "content": "Hello!"}]

334

)

335

```

336

337

### ConflictError (409)

338

339

```python { .api }

340

class ConflictError(APIStatusError):

341

"""

342

409 Conflict error.

343

344

Raised when the request conflicts with the current state of the resource.

345

"""

346

347

status_code: Literal[409] = 409

348

```

349

350

**Common Causes:**

351

352

- Attempting to create a resource that already exists

353

- Resource state conflicts with the operation

354

355

**Example:**

356

357

```python

358

import anthropic

359

from anthropic import ConflictError

360

361

client = anthropic.Anthropic(api_key="your-api-key")

362

363

try:

364

# Attempting operation that conflicts with resource state

365

result = client.beta.messages.batches.delete("batch-id")

366

except ConflictError as e:

367

print(f"Conflict: {e.message}")

368

print(f"Request ID: {e.request_id}")

369

print("The resource may be in a state that prevents this operation")

370

```

371

372

### RequestTooLargeError (413)

373

374

```python { .api }

375

class RequestTooLargeError(APIStatusError):

376

"""

377

413 Request Too Large error.

378

379

Raised when the request payload exceeds size limits.

380

"""

381

382

status_code: Literal[413] = 413

383

```

384

385

**Common Causes:**

386

387

- Request body too large

388

- Too many tokens in input

389

- Large file uploads

390

391

**Example:**

392

393

```python

394

import anthropic

395

from anthropic import RequestTooLargeError

396

397

client = anthropic.Anthropic(api_key="your-api-key")

398

399

try:

400

# Sending extremely large prompt

401

huge_content = "A" * 1000000 # Very large content

402

message = client.messages.create(

403

model="claude-3-5-sonnet-20241022",

404

max_tokens=1024,

405

messages=[{"role": "user", "content": huge_content}]

406

)

407

except RequestTooLargeError as e:

408

print(f"Request too large: {e.message}")

409

print(f"Request ID: {e.request_id}")

410

print("Please reduce the size of your request")

411

```

412

413

### UnprocessableEntityError (422)

414

415

```python { .api }

416

class UnprocessableEntityError(APIStatusError):

417

"""

418

422 Unprocessable Entity error.

419

420

Raised when the request is well-formed but contains semantic errors.

421

"""

422

423

status_code: Literal[422] = 422

424

```

425

426

**Common Causes:**

427

428

- Valid JSON but semantically invalid parameters

429

- Parameter values that violate business rules

430

- Incompatible parameter combinations

431

432

**Example:**

433

434

```python

435

import anthropic

436

from anthropic import UnprocessableEntityError

437

438

client = anthropic.Anthropic(api_key="your-api-key")

439

440

try:

441

# Invalid parameter combination

442

message = client.messages.create(

443

model="claude-3-5-sonnet-20241022",

444

max_tokens=0, # Invalid value

445

messages=[{"role": "user", "content": "Hello!"}]

446

)

447

except UnprocessableEntityError as e:

448

print(f"Unprocessable entity: {e.message}")

449

print(f"Request ID: {e.request_id}")

450

if e.body:

451

print(f"Validation errors: {e.body}")

452

```

453

454

### RateLimitError (429)

455

456

```python { .api }

457

class RateLimitError(APIStatusError):

458

"""

459

429 Rate Limit Exceeded error.

460

461

Raised when too many requests are made in a short time period.

462

"""

463

464

status_code: Literal[429] = 429

465

```

466

467

**Common Causes:**

468

469

- Exceeding requests per minute limit

470

- Exceeding tokens per minute limit

471

- Too many concurrent requests

472

473

**Example with Retry Logic:**

474

475

```python

476

import anthropic

477

from anthropic import RateLimitError

478

import time

479

480

client = anthropic.Anthropic(api_key="your-api-key")

481

482

def create_message_with_retry(max_retries=3):

483

"""Create message with exponential backoff on rate limits"""

484

for attempt in range(max_retries):

485

try:

486

message = client.messages.create(

487

model="claude-3-5-sonnet-20241022",

488

max_tokens=1024,

489

messages=[{"role": "user", "content": "Hello!"}]

490

)

491

return message

492

493

except RateLimitError as e:

494

if attempt < max_retries - 1:

495

# Exponential backoff: 1s, 2s, 4s

496

wait_time = 2 ** attempt

497

print(f"Rate limited. Retrying in {wait_time}s...")

498

print(f"Request ID: {e.request_id}")

499

500

# Check for Retry-After header

501

retry_after = e.response.headers.get("retry-after")

502

if retry_after:

503

wait_time = int(retry_after)

504

505

time.sleep(wait_time)

506

else:

507

print("Max retries reached")

508

raise

509

510

# Usage

511

try:

512

message = create_message_with_retry()

513

print(message.content[0].text)

514

except RateLimitError as e:

515

print(f"Still rate limited after retries: {e.message}")

516

```

517

518

### ServiceUnavailableError (503)

519

520

```python { .api }

521

class ServiceUnavailableError(APIStatusError):

522

"""

523

503 Service Unavailable error.

524

525

Raised when the API service is temporarily unavailable.

526

"""

527

528

status_code: Literal[503] = 503

529

```

530

531

**Common Causes:**

532

533

- Temporary service outage

534

- Maintenance

535

- Service degradation

536

537

**Example:**

538

539

```python

540

import anthropic

541

from anthropic import ServiceUnavailableError

542

import time

543

544

client = anthropic.Anthropic(api_key="your-api-key")

545

546

try:

547

message = client.messages.create(

548

model="claude-3-5-sonnet-20241022",

549

max_tokens=1024,

550

messages=[{"role": "user", "content": "Hello!"}]

551

)

552

except ServiceUnavailableError as e:

553

print(f"Service unavailable: {e.message}")

554

print(f"Request ID: {e.request_id}")

555

print("Please try again later")

556

557

# Retry after a delay

558

time.sleep(10)

559

message = client.messages.create(

560

model="claude-3-5-sonnet-20241022",

561

max_tokens=1024,

562

messages=[{"role": "user", "content": "Hello!"}]

563

)

564

```

565

566

### DeadlineExceededError (504)

567

568

```python { .api }

569

class DeadlineExceededError(APIStatusError):

570

"""

571

504 Gateway Timeout error.

572

573

Raised when the request times out on the server side.

574

"""

575

576

status_code: Literal[504] = 504

577

```

578

579

**Common Causes:**

580

581

- Server-side timeout processing request

582

- Complex operations taking too long

583

- Network issues between services

584

585

**Example:**

586

587

```python

588

import anthropic

589

from anthropic import DeadlineExceededError

590

591

client = anthropic.Anthropic(api_key="your-api-key")

592

593

try:

594

message = client.messages.create(

595

model="claude-3-5-sonnet-20241022",

596

max_tokens=4096, # Large response

597

messages=[{"role": "user", "content": "Write a very long story..."}]

598

)

599

except DeadlineExceededError as e:

600

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

601

print(f"Request ID: {e.request_id}")

602

print("Try reducing max_tokens or simplifying the request")

603

```

604

605

### OverloadedError (529)

606

607

```python { .api }

608

class OverloadedError(APIStatusError):

609

"""

610

529 Overloaded error.

611

612

Raised when Anthropic's API is temporarily overloaded.

613

"""

614

615

status_code: Literal[529] = 529

616

```

617

618

**Common Causes:**

619

620

- High system load

621

- Temporary capacity constraints

622

623

**Example:**

624

625

```python

626

import anthropic

627

from anthropic import OverloadedError

628

import time

629

630

client = anthropic.Anthropic(api_key="your-api-key")

631

632

def create_with_overload_retry(max_retries=5):

633

"""Retry with exponential backoff on overload errors"""

634

for attempt in range(max_retries):

635

try:

636

message = client.messages.create(

637

model="claude-3-5-sonnet-20241022",

638

max_tokens=1024,

639

messages=[{"role": "user", "content": "Hello!"}]

640

)

641

return message

642

643

except OverloadedError as e:

644

if attempt < max_retries - 1:

645

wait_time = min(2 ** attempt, 60) # Cap at 60 seconds

646

print(f"API overloaded. Retrying in {wait_time}s...")

647

print(f"Request ID: {e.request_id}")

648

time.sleep(wait_time)

649

else:

650

raise

651

652

try:

653

message = create_with_overload_retry()

654

print(message.content[0].text)

655

except OverloadedError as e:

656

print(f"API still overloaded: {e.message}")

657

```

658

659

### InternalServerError (5xx)

660

661

```python { .api }

662

class InternalServerError(APIStatusError):

663

"""

664

Generic 5xx server error.

665

666

Raised for other 5xx status codes not covered by specific exceptions.

667

"""

668

```

669

670

**Common Causes:**

671

672

- Unexpected server errors

673

- Internal service failures

674

675

**Example:**

676

677

```python

678

import anthropic

679

from anthropic import InternalServerError

680

681

client = anthropic.Anthropic(api_key="your-api-key")

682

683

try:

684

message = client.messages.create(

685

model="claude-3-5-sonnet-20241022",

686

max_tokens=1024,

687

messages=[{"role": "user", "content": "Hello!"}]

688

)

689

except InternalServerError as e:

690

print(f"Server error: {e.message}")

691

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

692

print(f"Request ID: {e.request_id}")

693

print("Please contact support if this persists")

694

```

695

696

## Connection Errors

697

698

### APIConnectionError

699

700

```python { .api }

701

class APIConnectionError(APIError):

702

"""

703

Connection error.

704

705

Raised when unable to establish a connection to the API.

706

"""

707

708

def __init__(

709

self,

710

*,

711

message: str = "Connection error.",

712

request: httpx.Request

713

) -> None: ...

714

```

715

716

**Common Causes:**

717

718

- Network connectivity issues

719

- DNS resolution failures

720

- Firewall blocking requests

721

- Invalid base URL

722

723

**Example:**

724

725

```python

726

import anthropic

727

from anthropic import APIConnectionError

728

729

try:

730

# Using invalid base URL

731

client = anthropic.Anthropic(

732

api_key="your-api-key",

733

base_url="https://invalid-url.example.com"

734

)

735

message = client.messages.create(

736

model="claude-3-5-sonnet-20241022",

737

max_tokens=1024,

738

messages=[{"role": "user", "content": "Hello!"}]

739

)

740

except APIConnectionError as e:

741

print(f"Connection failed: {e.message}")

742

print(f"Request URL: {e.request.url}")

743

print("Check your network connection and API endpoint")

744

```

745

746

### APITimeoutError

747

748

```python { .api }

749

class APITimeoutError(APIConnectionError):

750

"""

751

Request timeout error.

752

753

Raised when a request times out or is interrupted.

754

"""

755

756

def __init__(self, request: httpx.Request) -> None: ...

757

```

758

759

**Common Causes:**

760

761

- Request exceeding timeout limit

762

- Slow network connection

763

- Long-running operations

764

- Request cancellation

765

766

**Example:**

767

768

```python

769

import anthropic

770

from anthropic import APITimeoutError

771

import httpx

772

773

try:

774

# Set shorter timeout

775

client = anthropic.Anthropic(

776

api_key="your-api-key",

777

timeout=httpx.Timeout(10.0, connect=5.0) # 10s total, 5s connect

778

)

779

780

message = client.messages.create(

781

model="claude-3-5-sonnet-20241022",

782

max_tokens=4096,

783

messages=[{"role": "user", "content": "Write a very long essay..."}]

784

)

785

786

except APITimeoutError as e:

787

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

788

print(f"Request URL: {e.request.url}")

789

print("Try increasing the timeout or reducing the request complexity")

790

791

# Retry with longer timeout

792

client = anthropic.Anthropic(

793

api_key="your-api-key",

794

timeout=httpx.Timeout(60.0, connect=10.0)

795

)

796

797

message = client.messages.create(

798

model="claude-3-5-sonnet-20241022",

799

max_tokens=4096,

800

messages=[{"role": "user", "content": "Write a very long essay..."}]

801

)

802

```

803

804

## Validation Errors

805

806

### APIResponseValidationError

807

808

```python { .api }

809

class APIResponseValidationError(APIError):

810

"""

811

Response validation error.

812

813

Raised when the API response doesn't match the expected schema.

814

"""

815

816

response: httpx.Response

817

"""The HTTP response object"""

818

819

status_code: int

820

"""HTTP status code"""

821

822

def __init__(

823

self,

824

response: httpx.Response,

825

body: object | None,

826

*,

827

message: str | None = None

828

) -> None: ...

829

```

830

831

**Common Causes:**

832

833

- API returning unexpected data format

834

- Schema mismatch between SDK and API versions

835

- Corrupted response data

836

837

**Example:**

838

839

```python

840

import anthropic

841

from anthropic import APIResponseValidationError

842

843

client = anthropic.Anthropic(api_key="your-api-key")

844

845

try:

846

message = client.messages.create(

847

model="claude-3-5-sonnet-20241022",

848

max_tokens=1024,

849

messages=[{"role": "user", "content": "Hello!"}]

850

)

851

except APIResponseValidationError as e:

852

print(f"Invalid response: {e.message}")

853

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

854

print(f"Response body: {e.body}")

855

print("The API may have returned unexpected data")

856

print("Please ensure you're using the latest SDK version")

857

```

858

859

## Best Practices

860

861

### Comprehensive Error Handling

862

863

Handle different error types appropriately:

864

865

```python

866

import anthropic

867

from anthropic import (

868

AuthenticationError,

869

RateLimitError,

870

BadRequestError,

871

APIConnectionError,

872

APITimeoutError,

873

InternalServerError,

874

AnthropicError

875

)

876

import time

877

878

def create_message_robust(client, model, messages, max_tokens=1024):

879

"""Create message with comprehensive error handling"""

880

max_retries = 3

881

retry_count = 0

882

883

while retry_count < max_retries:

884

try:

885

return client.messages.create(

886

model=model,

887

max_tokens=max_tokens,

888

messages=messages

889

)

890

891

except AuthenticationError as e:

892

# Don't retry auth errors

893

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

894

print("Please check your API key")

895

raise

896

897

except BadRequestError as e:

898

# Don't retry bad requests

899

print(f"Bad request: {e.message}")

900

print(f"Request ID: {e.request_id}")

901

if e.body:

902

print(f"Details: {e.body}")

903

raise

904

905

except RateLimitError as e:

906

# Retry with exponential backoff

907

retry_count += 1

908

if retry_count >= max_retries:

909

raise

910

911

wait_time = 2 ** retry_count

912

retry_after = e.response.headers.get("retry-after")

913

if retry_after:

914

wait_time = int(retry_after)

915

916

print(f"Rate limited. Waiting {wait_time}s... (attempt {retry_count})")

917

time.sleep(wait_time)

918

919

except (APIConnectionError, APITimeoutError) as e:

920

# Retry connection/timeout errors

921

retry_count += 1

922

if retry_count >= max_retries:

923

raise

924

925

print(f"Connection issue. Retrying... (attempt {retry_count})")

926

time.sleep(2)

927

928

except InternalServerError as e:

929

# Retry server errors

930

retry_count += 1

931

if retry_count >= max_retries:

932

raise

933

934

print(f"Server error. Retrying... (attempt {retry_count})")

935

print(f"Request ID: {e.request_id}")

936

time.sleep(5)

937

938

except AnthropicError as e:

939

# Catch any other SDK errors

940

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

941

raise

942

943

# Usage

944

client = anthropic.Anthropic(api_key="your-api-key")

945

946

try:

947

message = create_message_robust(

948

client,

949

model="claude-3-5-sonnet-20241022",

950

messages=[{"role": "user", "content": "Hello!"}]

951

)

952

print(message.content[0].text)

953

954

except AnthropicError as e:

955

print(f"Failed after retries: {e}")

956

```

957

958

### Async Error Handling

959

960

Error handling in async contexts:

961

962

```python

963

import anthropic

964

from anthropic import RateLimitError, AnthropicError

965

import asyncio

966

967

async def create_message_async_robust(client, model, messages):

968

"""Async message creation with error handling"""

969

max_retries = 3

970

971

for attempt in range(max_retries):

972

try:

973

return await client.messages.create(

974

model=model,

975

max_tokens=1024,

976

messages=messages

977

)

978

979

except RateLimitError as e:

980

if attempt < max_retries - 1:

981

wait_time = 2 ** attempt

982

print(f"Rate limited. Waiting {wait_time}s...")

983

await asyncio.sleep(wait_time)

984

else:

985

raise

986

987

except AnthropicError as e:

988

print(f"Error: {e}")

989

raise

990

991

# Usage

992

async def main():

993

client = anthropic.AsyncAnthropic(api_key="your-api-key")

994

995

try:

996

message = await create_message_async_robust(

997

client,

998

model="claude-3-5-sonnet-20241022",

999

messages=[{"role": "user", "content": "Hello!"}]

1000

)

1001

print(message.content[0].text)

1002

1003

except AnthropicError as e:

1004

print(f"Failed: {e}")

1005

1006

finally:

1007

await client.close()

1008

1009

asyncio.run(main())

1010

```

1011

1012

### Logging and Monitoring

1013

1014

Log errors with context for debugging:

1015

1016

```python

1017

import anthropic

1018

from anthropic import APIStatusError, AnthropicError

1019

import logging

1020

1021

# Configure logging

1022

logging.basicConfig(

1023

level=logging.INFO,

1024

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

1025

)

1026

logger = logging.getLogger(__name__)

1027

1028

def create_message_with_logging(client, model, messages):

1029

"""Create message with detailed error logging"""

1030

try:

1031

logger.info(f"Creating message with model: {model}")

1032

1033

message = client.messages.create(

1034

model=model,

1035

max_tokens=1024,

1036

messages=messages

1037

)

1038

1039

logger.info(f"Message created successfully. ID: {message.id}")

1040

return message

1041

1042

except APIStatusError as e:

1043

# Log status errors with full context

1044

logger.error(

1045

f"API Status Error: {e.status_code}",

1046

extra={

1047

"status_code": e.status_code,

1048

"request_id": e.request_id,

1049

"message": e.message,

1050

"url": str(e.request.url),

1051

"body": e.body

1052

}

1053

)

1054

raise

1055

1056

except AnthropicError as e:

1057

# Log other SDK errors

1058

logger.error(f"Anthropic Error: {e}")

1059

raise

1060

1061

except Exception as e:

1062

# Log unexpected errors

1063

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

1064

raise

1065

1066

# Usage

1067

client = anthropic.Anthropic(api_key="your-api-key")

1068

1069

try:

1070

message = create_message_with_logging(

1071

client,

1072

model="claude-3-5-sonnet-20241022",

1073

messages=[{"role": "user", "content": "Hello!"}]

1074

)

1075

except AnthropicError:

1076

logger.error("Message creation failed")

1077

```

1078

1079

### Circuit Breaker Pattern

1080

1081

Implement circuit breaker to prevent cascading failures:

1082

1083

```python

1084

import anthropic

1085

from anthropic import AnthropicError, APIStatusError

1086

import time

1087

from enum import Enum

1088

1089

class CircuitState(Enum):

1090

CLOSED = "closed" # Normal operation

1091

OPEN = "open" # Blocking requests

1092

HALF_OPEN = "half_open" # Testing if service recovered

1093

1094

class CircuitBreaker:

1095

def __init__(self, failure_threshold=5, timeout=60):

1096

self.failure_threshold = failure_threshold

1097

self.timeout = timeout

1098

self.failures = 0

1099

self.last_failure_time = None

1100

self.state = CircuitState.CLOSED

1101

1102

def call(self, func, *args, **kwargs):

1103

"""Execute function with circuit breaker protection"""

1104

if self.state == CircuitState.OPEN:

1105

if time.time() - self.last_failure_time > self.timeout:

1106

self.state = CircuitState.HALF_OPEN

1107

else:

1108

raise Exception("Circuit breaker is OPEN")

1109

1110

try:

1111

result = func(*args, **kwargs)

1112

1113

# Success - reset failures

1114

if self.state == CircuitState.HALF_OPEN:

1115

self.state = CircuitState.CLOSED

1116

self.failures = 0

1117

1118

return result

1119

1120

except (APIStatusError, AnthropicError) as e:

1121

self.failures += 1

1122

self.last_failure_time = time.time()

1123

1124

if self.failures >= self.failure_threshold:

1125

self.state = CircuitState.OPEN

1126

1127

raise

1128

1129

# Usage

1130

client = anthropic.Anthropic(api_key="your-api-key")

1131

circuit_breaker = CircuitBreaker(failure_threshold=3, timeout=30)

1132

1133

def create_message():

1134

return client.messages.create(

1135

model="claude-3-5-sonnet-20241022",

1136

max_tokens=1024,

1137

messages=[{"role": "user", "content": "Hello!"}]

1138

)

1139

1140

try:

1141

message = circuit_breaker.call(create_message)

1142

print(message.content[0].text)

1143

except Exception as e:

1144

print(f"Error: {e}")

1145

```

1146

1147

### Graceful Degradation

1148

1149

Implement fallback strategies when errors occur:

1150

1151

```python

1152

import anthropic

1153

from anthropic import AnthropicError, RateLimitError, InternalServerError

1154

1155

class MessageService:

1156

def __init__(self, api_key, fallback_model=None):

1157

self.client = anthropic.Anthropic(api_key=api_key)

1158

self.primary_model = "claude-3-5-sonnet-20241022"

1159

self.fallback_model = fallback_model or "claude-3-haiku-20240307"

1160

1161

def create_message(self, messages, max_tokens=1024, allow_fallback=True):

1162

"""Create message with automatic fallback to different model"""

1163

# Try primary model

1164

try:

1165

return self.client.messages.create(

1166

model=self.primary_model,

1167

max_tokens=max_tokens,

1168

messages=messages

1169

)

1170

1171

except RateLimitError as e:

1172

if not allow_fallback:

1173

raise

1174

1175

print(f"Primary model rate limited. Trying fallback model...")

1176

# Try fallback model

1177

try:

1178

return self.client.messages.create(

1179

model=self.fallback_model,

1180

max_tokens=max_tokens,

1181

messages=messages

1182

)

1183

except AnthropicError:

1184

# If fallback also fails, raise original error

1185

raise e

1186

1187

except InternalServerError as e:

1188

if not allow_fallback:

1189

raise

1190

1191

print(f"Primary model error. Trying fallback model...")

1192

try:

1193

return self.client.messages.create(

1194

model=self.fallback_model,

1195

max_tokens=max_tokens,

1196

messages=messages

1197

)

1198

except AnthropicError:

1199

raise e

1200

1201

# Usage

1202

service = MessageService(api_key="your-api-key")

1203

1204

try:

1205

message = service.create_message(

1206

messages=[{"role": "user", "content": "Hello!"}]

1207

)

1208

print(message.content[0].text)

1209

except AnthropicError as e:

1210

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

1211

```

1212

1213

## Retry Strategies

1214

1215

### Exponential Backoff with Jitter

1216

1217

Implement exponential backoff with jitter to avoid thundering herd:

1218

1219

```python

1220

import anthropic

1221

from anthropic import RateLimitError, InternalServerError

1222

import time

1223

import random

1224

1225

def create_message_with_backoff(

1226

client,

1227

model,

1228

messages,

1229

max_retries=5,

1230

base_delay=1,

1231

max_delay=60

1232

):

1233

"""Create message with exponential backoff and jitter"""

1234

for attempt in range(max_retries):

1235

try:

1236

return client.messages.create(

1237

model=model,

1238

max_tokens=1024,

1239

messages=messages

1240

)

1241

1242

except (RateLimitError, InternalServerError) as e:

1243

if attempt == max_retries - 1:

1244

raise

1245

1246

# Calculate exponential backoff with jitter

1247

exponential_delay = min(base_delay * (2 ** attempt), max_delay)

1248

jitter = random.uniform(0, exponential_delay * 0.1)

1249

delay = exponential_delay + jitter

1250

1251

print(f"Attempt {attempt + 1} failed. Retrying in {delay:.2f}s...")

1252

print(f"Error: {e.message}")

1253

if hasattr(e, 'request_id'):

1254

print(f"Request ID: {e.request_id}")

1255

1256

time.sleep(delay)

1257

1258

# Usage

1259

client = anthropic.Anthropic(api_key="your-api-key")

1260

1261

message = create_message_with_backoff(

1262

client,

1263

model="claude-3-5-sonnet-20241022",

1264

messages=[{"role": "user", "content": "Hello!"}]

1265

)

1266

print(message.content[0].text)

1267

```

1268

1269

## Common Imports

1270

1271

```python

1272

from anthropic import (

1273

# Base exceptions

1274

AnthropicError,

1275

APIError,

1276

APIStatusError,

1277

1278

# HTTP status errors

1279

BadRequestError,

1280

AuthenticationError,

1281

PermissionDeniedError,

1282

NotFoundError,

1283

ConflictError,

1284

RequestTooLargeError,

1285

UnprocessableEntityError,

1286

RateLimitError,

1287

ServiceUnavailableError,

1288

DeadlineExceededError,

1289

OverloadedError,

1290

InternalServerError,

1291

1292

# Connection errors

1293

APIConnectionError,

1294

APITimeoutError,

1295

1296

# Validation errors

1297

APIResponseValidationError,

1298

)

1299

```

1300