Skip to main content

Exception hierarchy

All Vrin SDK exceptions inherit from VRINError:
VRINError
  +-- AuthenticationError    # Invalid/expired API key (401)
  +-- RateLimitError         # Rate limit exceeded (429)
  +-- ValidationError        # Invalid input
  +-- ServiceUnavailableError # Server error (5xx)
  +-- JobFailedError         # Async job failed
  +-- TimeoutError           # Operation timed out
  +-- InsufficientCoverageError  # No relevant knowledge
  +-- StreamingError         # SSE stream error

Basic error handling

from vrin import VRINClient, VRINError

client = VRINClient(api_key="vrin_abc123")

try:
    result = client.query("What is ACME's revenue?")
except VRINError as e:
    print(f"Vrin error: {e}")

Granular error handling

from vrin import (
    VRINClient,
    AuthenticationError,
    RateLimitError,
    ServiceUnavailableError,
    TimeoutError,
    VRINError,
)

try:
    result = client.query("What is ACME's revenue?")
except AuthenticationError:
    # API key is invalid or expired -- cannot retry
    print("Check your API key")
except RateLimitError:
    # Back off and retry
    print("Rate limited -- wait before retrying")
except ServiceUnavailableError:
    # Server error -- the client already retried (max_retries times)
    print("Service temporarily unavailable")
except TimeoutError:
    # Request took too long
    print("Request timed out")
except VRINError as e:
    # Catch-all for any other Vrin error
    print(f"Unexpected error: {e}")

Retry patterns

The client has built-in retry for server errors (5xx) and connection failures. For rate limits, implement your own backoff:
import time
from vrin import RateLimitError

def query_with_backoff(client, query, max_attempts=3):
    for attempt in range(max_attempts):
        try:
            return client.query(query)
        except RateLimitError:
            if attempt < max_attempts - 1:
                wait = 2 ** attempt
                time.sleep(wait)
                continue
            raise

Handling async job failures

from vrin import JobFailedError, TimeoutError

try:
    result = client.insert("content...", title="My Doc", max_wait=60.0)
except JobFailedError as e:
    print(f"Processing failed: {e}")
    # Content may be partially indexed -- check job status for details
except TimeoutError:
    print("Job still running -- check status manually")
    # The job may still complete successfully

Streaming error handling

from vrin import StreamingError

try:
    for token in client.query("test", stream=True):
        print(token, end="")
except StreamingError as e:
    print(f"\nStream error: {e}")
You can also check for errors after iteration:
resp = client.query("test", stream=True)
for token in resp:
    print(token, end="")

if resp.error:
    print(f"\nError during stream: {resp.error}")
if resp.insufficient_coverage:
    print("\nNo relevant knowledge found")

Insufficient coverage

When the knowledge base has no relevant facts, Vrin returns early without calling the LLM:
result = client.query("What is the weather on Mars?")
if result.get("insufficient_coverage"):
    print("I don't have knowledge about this topic")
else:
    print(result["summary"])
This is not an error — it means the query is outside the scope of your knowledge base.