FastPII Docs
FastPII Connect

Error Handling

Complete error hierarchy for FastPII Connect — API errors, Gateway errors, and error handling patterns for Python and TypeScript.

Error Handling

All FastPII Connect errors inherit from FastPIIError, making it easy to catch specific errors or handle all errors at once.

Error hierarchy

FastPIIError
├── AuthenticationError         (401)
├── PermissionError              (403)
│   ├── QuotaExceededError      (403 + type=quota_exceeded)
│   └── PolicyViolationError    (403 + type=policy_violation)
├── ValidationError              (400, 422)
├── NotFoundError                (404)
├── RateLimitError               (429)
├── ServerError                  (5xx)
├── ConnectionError              (network failures)
├── TimeoutError                 (request timeouts)
└── GatewayError                 (Gateway base)
    ├── PolicyBlockError         (403)
    ├── PIIInspectionError       (503)
    └── ProviderUnavailableError (502)

API errors

These errors are returned by the Connect API (https://api.fastpii.com):

ErrorStatusWhenKey attributes
AuthenticationError401Invalid or missing API keymessage, request_id
PermissionError403Insufficient permissionsmessage, error_type, request_id
QuotaExceededError403Monthly quota exceededmessage, request_id
PolicyViolationError403Request violates policymessage, request_id
ValidationError400/422Invalid request parametersmessage, status_code, request_id
NotFoundError404Resource not foundmessage, request_id
RateLimitError429Rate limit exceededmessage, retry_after, request_id
ServerError500+Internal server errormessage, status_code, request_id
ConnectionErrorNoneNetwork failure (no response)message
TimeoutErrorNoneRequest timeout (no response)message

QuotaExceededError vs PolicyViolationError

Both are PermissionError subclasses with status 403, but they have different error_type values:

  • QuotaExceededError: error_type="quota_exceeded" — your monthly API call quota has been reached
  • PolicyViolationError: error_type="policy_violation" — the request content violates your workspace policy

Gateway errors

These errors are specific to the Gateway (https://gateway.fastpii.com):

ErrorStatusWhenKey attributes
PolicyBlockError403Request blocked by workspace PII policy before reaching the LLMmessage, request_id
PIIInspectionError503LLM response blocked because PII was detected in the outputmessage, request_id
ProviderUnavailableError502Upstream LLM provider unavailable or returned an errormessage, request_id

PolicyBlockError vs PIIInspectionError

  • PolicyBlockError: The request was blocked before being sent to the LLM. Your workspace policy detected PII in the input messages.
  • PIIInspectionError: The response from the LLM was blocked. PII was detected in the model's output and the response was not returned to you.

Python error handling

from fastpii_connect.errors import (
    FastPIIError,
    AuthenticationError,
    PermissionError,
    QuotaExceededError,
    PolicyViolationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
    ServerError,
    ConnectionError,
    TimeoutError,
    GatewayError,
    PolicyBlockError,
    PIIInspectionError,
    ProviderUnavailableError,
)

# --- API errors ---

try:
    result = client.detect("text")
except AuthenticationError as e:
    print(f"Invalid API key: {e.message}")
except QuotaExceededError as e:
    print(f"Quota exceeded: {e.message}")
except PolicyViolationError as e:
    print(f"Policy violation: {e.message}")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except ValidationError as e:
    print(f"Bad request: {e.message} (status {e.status_code})")
except ServerError as e:
    print(f"Server error: {e.message} (status {e.status_code})")
except ConnectionError as e:
    print(f"Network error: {e.message}")
except TimeoutError as e:
    print(f"Timeout: {e.message}")
except FastPIIError as e:
    print(f"FastPII error: {e.message}")

# --- Gateway errors ---

try:
    response = client.gateway.chat.completions(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello!"}],
    )
except PolicyBlockError as e:
    print(f"Request blocked by PII policy: {e.message}")
except PIIInspectionError as e:
    print(f"Response contained PII: {e.message}")
except ProviderUnavailableError as e:
    print(f"LLM provider unavailable: {e.message}")
except GatewayError as e:
    print(f"Gateway error: {e.message} (type={e.error_type})")

Python error attributes

AttributeTypeDescription
messagestrHuman-readable error message
status_codeint or NoneHTTP status code (None for network errors)
error_typestr or NoneMachine-readable error type
request_idstr or NoneRequest ID for debugging (from X-Request-ID header)
retry_afterint or NoneSeconds to wait before retrying (RateLimitError only)

TypeScript error handling

import {
  FastPIIError,
  AuthenticationError,
  PermissionError,
  QuotaExceededError,
  PolicyViolationError,
  ValidationError,
  NotFoundError,
  RateLimitError,
  ServerError,
  ConnectionError,
  TimeoutError,
  GatewayError,
  PolicyBlockError,
  PIIInspectionError,
  ProviderUnavailableError,
} from "fastpii-connect";

// --- API errors ---

try {
  const result = await client.detect("text");
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.log(`Invalid API key: ${error.message}`);
  } else if (error instanceof QuotaExceededError) {
    console.log(`Quota exceeded: ${error.message}`);
  } else if (error instanceof PolicyViolationError) {
    console.log(`Policy violation: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof ValidationError) {
    console.log(`Bad request: ${error.message} (status ${error.statusCode})`);
  } else if (error instanceof ServerError) {
    console.log(`Server error: ${error.message} (status ${error.statusCode})`);
  } else if (error instanceof ConnectionError) {
    console.log(`Network error: ${error.message}`);
  } else if (error instanceof TimeoutError) {
    console.log(`Timeout: ${error.message}`);
  } else if (error instanceof FastPIIError) {
    console.log(`FastPII error: ${error.message}`);
  }
}

// --- Gateway errors ---

try {
  const response = await client.gateway.chat.completions({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello!" }],
  });
} catch (error) {
  if (error instanceof PolicyBlockError) {
    console.log(`Request blocked by PII policy: ${error.message}`);
  } else if (error instanceof PIIInspectionError) {
    console.log(`Response contained PII: ${error.message}`);
  } else if (error instanceof ProviderUnavailableError) {
    console.log(`LLM provider unavailable: ${error.message}`);
  } else if (error instanceof GatewayError) {
    console.log(`Gateway error: ${error.message} (type=${error.errorType})`);
  }
}

TypeScript error properties

PropertyTypeDescription
messagestringHuman-readable error message (inherited from Error)
statusCodenumber | nullHTTP status code (null for network errors)
errorTypestring | nullMachine-readable error type
requestIdstring | nullRequest ID for debugging (from X-Request-ID header)
retryAfternumber | nullSeconds to wait before retrying (RateLimitError only)

Automatic retries

Both the API client and Gateway client automatically retry on transient errors:

  • Retryable status codes: 408, 429, 502, 503, 504
  • Retryable methods: GET, HEAD, PUT, DELETE (POST is not retried by default)
  • Retry count: Configurable via max_retries (default: 2)
  • Backoff: Exponential with jitter — 0.5 * 2^attempt ± 25% jitter
  • Rate limit: On 429, the Retry-After header value is used as the backoff
# Python: increase retries
client = FastPIIClient(api_key="fpk_...", max_retries=4)
// TypeScript: increase retries
const client = new FastPIIClient({ apiKey: "fpk_...", maxRetries: 4 });

Streaming errors

When using Gateway streaming, errors can appear as events within the stream:

from fastpii_connect import ChatCompletionChunk, StreamDone, StreamError
from fastpii_connect.errors import PolicyBlockError, PIIInspectionError

for event in client.gateway.chat.stream(model="gpt-4o", messages=[...]):
    if isinstance(event, StreamError):
        # Stream errors are automatically raised as exceptions
        # This code is unreachable unless you catch them
        pass
    elif isinstance(event, ChatCompletionChunk):
        print(event.content, end="")
    elif isinstance(event, StreamDone):
        print("\n[Done]")

Stream errors are automatically converted to their corresponding exception types (PolicyBlockError, PIIInspectionError, ProviderUnavailableError, or GatewayError). You catch them the same way as non-streaming errors.

Request IDs

Every request includes a unique X-Request-ID header (format: fpi_<16-hex-chars>). When contacting support, include the request_id from the error:

try:
    result = client.detect("text")
except FastPIIError as e:
    print(f"Error: {e.message}, Request ID: {e.request_id}")
    # Include e.request_id in your support request
try {
  const result = await client.detect("text");
} catch (error) {
  if (error instanceof FastPIIError) {
    console.log(`Error: ${error.message}, Request ID: ${error.requestId}`);
    // Include error.requestId in your support request
  }
}

On this page