Handling Errors and Retries

1. Understanding Pinecone Error Types

ErrorHTTPMeaning
PineconeApiExceptionvariesGeneral API error
NotFoundException404Index/namespace missing
UnauthorizedException401Bad API key
ForbiddenException403No permission
PineconeApiAttributeErrorSDK misuse
ServiceException5xxServer-side

2. Implementing Exponential Backoff

Example: Backoff Wrapper

import time, random

def with_backoff(fn, *args, max_tries=5, **kw):
    for i in range(max_tries):
        try:
            return fn(*args, **kw)
        except Exception as e:
            if i == max_tries - 1: raise
            wait = (2 ** i) + random.random()
            time.sleep(wait)

3. Handling Rate Limits

Example: 429 Handler

from pinecone.exceptions import PineconeApiException

try:
    index.upsert(vectors=batch)
except PineconeApiException as e:
    if e.status == 429:
        time.sleep(int(e.headers.get("Retry-After", "5")))
        index.upsert(vectors=batch)
    else: raise

4. Implementing Retry Logic

Example: Tenacity

from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(5),
       wait=wait_exponential(min=1, max=30))
def safe_query(qv):
    return index.query(vector=qv, top_k=10)

5. Handling Network Errors

ErrorAction
ConnectionErrorRetry with backoff
TimeoutRetry; check region/proxy
DNSVerify endpoint host

6. Handling Timeout Errors

Example: Custom Timeout

from pinecone import Pinecone
pc = Pinecone(api_key="...", additional_headers={"x-request-timeout": "30"})

7. Implementing Circuit Breakers

Example: pybreaker

import pybreaker
breaker = pybreaker.CircuitBreaker(fail_max=5, reset_timeout=30)

@breaker
def query(qv):
    return index.query(vector=qv, top_k=10)

8. Handling Partial Failures

Example: Per-Batch Failure

failed = []
for b in batches:
    try: index.upsert(vectors=b)
    except Exception: failed.append(b)
# retry failed later
for b in failed: with_backoff(index.upsert, vectors=b)

9. Logging Error Details

Example: Structured Error Log

try:
    index.query(vector=qv, top_k=10)
except PineconeApiException as e:
    log.error("pinecone_query_failed", extra={
        "status": e.status,
        "reason": e.reason,
        "body": getattr(e, "body", None),
    })
    raise

10. Implementing Idempotent Operations

Note: Upserts are naturally idempotent by ID — re-running the same upsert produces the same result. Use stable, deterministic IDs.

11. Recovering from Failed Upserts

StrategyDetail
Persist failed IDsTo dead-letter queue
Replay laterBackoff job
Verify with fetchConfirm presence

12. Handling Index State Errors

Example: Wait for Ready

while not pc.describe_index("docs").status["ready"]:
    time.sleep(2)
index = pc.Index("docs")