Exceptions

This module defines the exception hierarchy for PIPolars. All exceptions inherit from PIPolarsError, making it easy to catch any library-related error.

Exception Hierarchy

PIPolarsError
├── PIConnectionError
│   └── PIAuthenticationError
├── PIDataError
│   ├── PIPointNotFoundError
│   └── PIBulkOperationError
├── PIQueryError
│   └── PITimeParseError
├── PIConfigurationError
├── PIAFSDKError
├── PICacheError
└── PITransformError

Base Exception

PIPolarsError

class pipolars.PIPolarsError[source]

Bases: Exception

Base exception for all PIPolars errors.

All custom exceptions in the library inherit from this class, making it easy to catch any PIPolars-related error.

message

Human-readable error message

details

Optional dictionary with additional error context

Base exception for all PIPolars errors.

message: str

Human-readable error message.

details: dict[str, Any]

Optional dictionary with additional error context.

__init__(message, details=None)[source]

Usage:

from pipolars.core.exceptions import PIPolarsError

try:
    df = client.recorded_values("TAG", "*-1h", "*")
except PIPolarsError as e:
    print(f"Error: {e.message}")
    print(f"Details: {e.details}")

Connection Exceptions

PIConnectionError

class pipolars.PIConnectionError[source]

Bases: PIPolarsError

Raised when connection to PI System fails.

This exception is raised when: - PI Server is unreachable - Authentication fails - AF Database connection fails - Network timeout occurs

Raised when connection to PI System fails.

server: str | None

The server that failed to connect.

Raised when:

  • PI Server is unreachable

  • Authentication fails

  • AF Database connection fails

  • Network timeout occurs

__init__(message, server=None, details=None)[source]

PIAuthenticationError

class pipolars.core.exceptions.PIAuthenticationError[source]

Bases: PIConnectionError

Raised when PI System authentication fails.

This exception is raised when: - Invalid credentials provided - User lacks permissions - Kerberos/NTLM authentication fails

Raised when PI System authentication fails.

Raised when:

  • Invalid credentials provided

  • User lacks permissions

  • Kerberos/NTLM authentication fails

Usage:

from pipolars.core.exceptions import PIConnectionError, PIAuthenticationError

try:
    with PIClient("my-server") as client:
        df = client.snapshot("TAG")
except PIAuthenticationError as e:
    print(f"Auth failed: {e}")
except PIConnectionError as e:
    print(f"Connection failed to {e.server}: {e}")

Data Exceptions

PIDataError

class pipolars.PIDataError[source]

Bases: PIPolarsError

Raised when data retrieval or conversion fails.

This exception is raised when: - Requested tag doesn’t exist - Data type conversion fails - Invalid time range specified - Bulk operation partially fails

Raised when data retrieval or conversion fails.

tag: str | None

The tag that caused the error.

Raised when:

  • Requested tag doesn’t exist

  • Data type conversion fails

  • Invalid time range specified

  • Bulk operation partially fails

__init__(message, tag=None, details=None)[source]

PIPointNotFoundError

class pipolars.core.exceptions.PIPointNotFoundError[source]

Bases: PIDataError

Raised when a PI Point (tag) cannot be found.

This exception is raised when: - Tag name doesn’t exist in the PI Data Archive - Tag was deleted or renamed - User lacks access to the tag

Raised when a PI Point (tag) cannot be found.

Raised when:

  • Tag name doesn’t exist in the PI Data Archive

  • Tag was deleted or renamed

  • User lacks access to the tag

__init__(tag, server=None)[source]

Usage:

from pipolars.core.exceptions import PIPointNotFoundError

try:
    df = client.snapshot("NONEXISTENT_TAG")
except PIPointNotFoundError as e:
    print(f"Tag not found: {e.tag}")

PIBulkOperationError

class pipolars.core.exceptions.PIBulkOperationError[source]

Bases: PIDataError

Raised when a bulk operation partially fails.

This exception contains information about which operations succeeded and which failed.

succeeded

List of tags that succeeded

failed

Dictionary mapping failed tags to their error messages

Raised when a bulk operation partially fails.

succeeded: list[str]

List of tags that succeeded.

failed: dict[str, str]

Dictionary mapping failed tags to their error messages.

__init__(message, succeeded, failed)[source]

Usage:

from pipolars.core.exceptions import PIBulkOperationError

try:
    df = client.recorded_values(
        ["TAG1", "TAG2", "INVALID", "TAG3"],
        "*-1h", "*"
    )
except PIBulkOperationError as e:
    print(f"Succeeded: {e.succeeded}")
    print(f"Failed: {e.failed}")

    # Process successful results
    for tag in e.succeeded:
        print(f"Got data for {tag}")

Query Exceptions

PIQueryError

class pipolars.PIQueryError[source]

Bases: PIPolarsError

Raised when a PI query is invalid or fails.

This exception is raised when: - Invalid time expression provided - Query syntax error - Query timeout - Too many results requested

Raised when a PI query is invalid or fails.

query: str | None

The query that failed.

Raised when:

  • Invalid time expression provided

  • Query syntax error

  • Query timeout

  • Too many results requested

__init__(message, query=None, details=None)[source]

PITimeParseError

class pipolars.core.exceptions.PITimeParseError[source]

Bases: PIQueryError

Raised when a time expression cannot be parsed.

This exception is raised when: - Invalid relative time expression (e.g., “*-invalid”) - Malformed absolute timestamp - Unsupported time format

Raised when a time expression cannot be parsed.

Raised when:

  • Invalid relative time expression (e.g., "*-invalid")

  • Malformed absolute timestamp

  • Unsupported time format

__init__(expression, reason=None)[source]

Usage:

from pipolars.core.exceptions import PITimeParseError

try:
    df = client.recorded_values("TAG", "invalid-time", "*")
except PITimeParseError as e:
    print(f"Invalid time: {e}")

Other Exceptions

PIConfigurationError

class pipolars.core.exceptions.PIConfigurationError[source]

Bases: PIPolarsError

Raised when configuration is invalid.

This exception is raised when: - Required configuration missing - Invalid configuration value - Configuration file parse error

Raised when configuration is invalid.

Raised when:

  • Required configuration missing

  • Invalid configuration value

  • Configuration file parse error

PIAFSDKError

class pipolars.core.exceptions.PIAFSDKError[source]

Bases: PIPolarsError

Raised when the AF SDK encounters an error.

This exception wraps errors from the underlying OSIsoft AF SDK and provides additional context.

sdk_error_code

The error code from AF SDK if available

sdk_message

The original error message from AF SDK

Raised when the AF SDK encounters an error.

sdk_error_code: int | None

The error code from AF SDK if available.

sdk_message: str | None

The original error message from AF SDK.

__init__(message, sdk_error_code=None, sdk_message=None)[source]

PICacheError

class pipolars.core.exceptions.PICacheError[source]

Bases: PIPolarsError

Raised when cache operations fail.

This exception is raised when: - Cache read/write fails - Cache corruption detected - Cache storage is full

Raised when cache operations fail.

Raised when:

  • Cache read/write fails

  • Cache corruption detected

  • Cache storage is full

PITransformError

class pipolars.core.exceptions.PITransformError[source]

Bases: PIPolarsError

Raised when data transformation fails.

This exception is raised when: - Cannot convert PI type to Polars type - Schema mismatch - Data validation fails

Raised when data transformation fails.

Raised when:

  • Cannot convert PI type to Polars type

  • Schema mismatch

  • Data validation fails

Error Handling Patterns

Catch All PIPolars Errors

from pipolars.core.exceptions import PIPolarsError

try:
    with PIClient("my-server") as client:
        df = client.recorded_values("TAG", "*-1h", "*")
except PIPolarsError as e:
    print(f"PIPolars error: {e}")
    print(f"Details: {e.details}")

Specific Error Handling

from pipolars.core.exceptions import (
    PIConnectionError,
    PIPointNotFoundError,
    PITimeParseError,
    PIPolarsError,
)

def safe_query(client, tag, start, end):
    try:
        return client.recorded_values(tag, start, end)

    except PIPointNotFoundError:
        print(f"Tag '{tag}' not found, skipping...")
        return None

    except PITimeParseError as e:
        print(f"Invalid time expression: {e}")
        raise ValueError("Invalid time range") from e

    except PIConnectionError as e:
        print(f"Connection lost to {e.server}")
        raise

    except PIPolarsError as e:
        print(f"Unexpected error: {e}")
        raise

Retry Pattern

import time
from pipolars.core.exceptions import PIConnectionError

def query_with_retry(client, tag, start, end, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.recorded_values(tag, start, end)
        except PIConnectionError as e:
            if attempt < max_retries - 1:
                print(f"Retry {attempt + 1}/{max_retries}...")
                time.sleep(2 ** attempt)
            else:
                raise

See Also