Exception Handling

Custom exceptions for NEPSE Client.

This module provides a comprehensive exception hierarchy for handling various error scenarios when interacting with the NEPSE API.

exception nepse_client.exceptions.NepseError[source]

Bases: Exception

Base exception class for all NEPSE-related errors.

All custom exceptions in this library inherit from this class, allowing for easy catch-all error handling.

message

Human-readable error description

status_code

HTTP status code (if applicable)

response_data

Raw response data from the API

request_data

Original request data

__init__(message, status_code=None, response_data=None, request_data=None)[source]

Initialize NepseError.

Parameters:
  • message (str) – Error description

  • status_code (Optional[int]) – HTTP status code

  • response_data (Optional[Any]) – Response from the API

  • request_data (Optional[dict[str, Any]]) – Original request data

__str__()[source]

Return string representation of the error.

Return type:

str

__repr__()[source]

Return detailed representation of the error.

Return type:

str

to_dict()[source]

Convert exception to dictionary for logging/serialization.

Return type:

dict[str, Any]

Returns:

Dictionary representation of the exception

exception nepse_client.exceptions.NepseClientError[source]

Bases: NepseError

Raised when client sends an invalid request (4xx errors).

This typically indicates: - Invalid parameters - Missing required fields - Malformed request data - Invalid company symbol

Example

>>> try:
...     client.getCompanyDetails("INVALID")
... except NepseClientError as e:
...     print(f"Invalid request: {e}")
__init__(message='Invalid client request', status_code=400, response_data=None, request_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

  • request_data (dict[str, Any] | None)

exception nepse_client.exceptions.NepseAuthenticationError[source]

Bases: NepseError

Raised when access token has expired (401 Unauthorized).

This exception is typically handled automatically by the client, which will refresh the token and retry the request.

Note

Users usually don’t need to handle this exception directly as the client manages token refresh automatically.

__init__(message='Authentication token expired', status_code=401, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

exception nepse_client.exceptions.NepseBadGatewayError[source]

Bases: NepseError

Raised when server returns 502 Bad Gateway.

This typically indicates: - Server temporarily unavailable - Upstream server issues - Network problems between servers

Recommended action: Retry the request after a short delay.

__init__(message='Bad Gateway - Server temporarily unavailable', status_code=502, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

exception nepse_client.exceptions.NepseServerError[source]

Bases: NepseError

Generic server error for 5xx status codes.

This indicates an error on the NEPSE server side. Common causes: - Internal server error (500) - Service unavailable (503) - Gateway timeout (504)

Recommended action: Retry with exponential backoff or contact support.

__init__(message='Server error occurred', status_code=500, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

exception nepse_client.exceptions.NepseNetworkError[source]

Bases: NepseError

Raised for general network or unexpected HTTP issues.

This covers: - Connection timeouts - DNS resolution failures - SSL/TLS errors - Unexpected response formats - Network interruptions

Recommended action: Check network connectivity and retry.

__init__(message='Network error occurred', status_code=None, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int | None)

  • response_data (Any | None)

exception nepse_client.exceptions.NepseValidationError[source]

Bases: NepseError

Raised when input validation fails before making API request.

This is raised for client-side validation errors such as: - Invalid date formats - Out of range values - Missing required parameters - Invalid data types

Example

>>> try:
...     client.getCompanyPriceVolumeHistory("NABIL", start_date="invalid")
... except NepseValidationError as e:
...     print(f"Validation error: {e}")
__init__(message='Input validation failed', field=None, value=None)[source]

Initialize validation error.

Parameters:
  • message (str) – Error description

  • field (Optional[str]) – Name of the invalid field

  • value (Optional[Any]) – Invalid value provided

exception nepse_client.exceptions.NepseRateLimitError[source]

Bases: NepseError

Raised when API rate limit is exceeded (429 Too Many Requests).

retry_after

Seconds to wait before retrying (if provided by server)

__init__(message='Rate limit exceeded', status_code=429, retry_after=None)[source]

Initialize rate limit error.

Parameters:
  • message (str) – Error description

  • status_code (int) – HTTP status code

  • retry_after (Optional[int]) – Seconds to wait before retry

exception nepse_client.exceptions.NepseDataNotFoundError[source]

Bases: NepseError

Raised when requested data is not found.

This is used when: - Company symbol doesn’t exist - No data available for requested date - Empty result sets

Example

>>> try:
...     client.getFloorSheetOf("INVALID", "2024-01-01")
... except NepseDataNotFoundError as e:
...     print(f"Data not found: {e}")
__init__(message='Requested data not found', resource=None)[source]

Initialize data not found error.

Parameters:
  • message (str) – Error description

  • resource (Optional[str]) – Resource that was not found

exception nepse_client.exceptions.NepseTimeoutError[source]

Bases: NepseError

Raised when request times out.

This occurs when the server doesn’t respond within the specified timeout period.

timeout

Timeout value in seconds

__init__(message='Request timeout', timeout=None)[source]

Initialize timeout error.

Parameters:
  • message (str) – Error description

  • timeout (Optional[float]) – Timeout value in seconds

exception nepse_client.exceptions.NepseConnectionError[source]

Bases: NepseError

Raised when connection to NEPSE server fails.

This is different from NepseNetworkError as it specifically indicates inability to establish a connection.

__init__(message='Failed to connect to NEPSE server')[source]

Initialize the exception with a default message.

Parameters:

message (str)

exception nepse_client.exceptions.NepseConfigurationError[source]

Bases: NepseError

Raised when there’s an issue with client configuration.

This includes: - Missing required configuration files - Invalid configuration values - Corrupted data files

__init__(message='Configuration error')[source]

Initialize the exception with a default message.

Parameters:

message (str)

nepse_client.exceptions.get_exception_for_status(status_code, message, response_data=None)[source]

Get appropriate exception class for HTTP status code.

Parameters:
  • status_code (int) – HTTP status code

  • message (str) – Error message

  • response_data (Optional[Any]) – Response data from API

Return type:

NepseError

Returns:

Appropriate exception instance

Exception Hierarchy

The nepse-client library uses a comprehensive exception hierarchy:

NepseError (Base)
├── NepseClientError (4xx errors)
├── NepseAuthenticationError (401 errors)
├── NepseBadGatewayError (502 errors)
├── NepseServerError (5xx errors)
├── NepseNetworkError (connection errors)
├── NepseValidationError (validation errors)
├── NepseRateLimitError (429 errors)
├── NepseDataNotFoundError (404 errors)
├── NepseTimeoutError (timeout errors)
├── NepseConnectionError (connection failures)
└── NepseConfigurationError (config errors)

Base Exception

NepseError

class nepse_client.NepseError[source]

Bases: Exception

Base exception class for all NEPSE-related errors.

All custom exceptions in this library inherit from this class, allowing for easy catch-all error handling.

message

Human-readable error description

status_code

HTTP status code (if applicable)

response_data

Raw response data from the API

request_data

Original request data

Base exception for all NEPSE-related errors.

Attributes:

  • message (str): Human-readable error description

  • status_code (Optional[int]): HTTP status code if applicable

  • response_data (Optional[Any]): Raw response data from API

  • request_data (Optional[Dict]): Original request data

Example:

from nepse_client import NepseClient, NepseError

client = NepseClient()

try:
   data = client.getMarketStatus()
except NepseError as e:
   print(f"Error: {e}")
   print(f"Status code: {e.status_code}")
__init__(message, status_code=None, response_data=None, request_data=None)[source]

Initialize NepseError.

Parameters:
  • message (str) – Error description

  • status_code (Optional[int]) – HTTP status code

  • response_data (Optional[Any]) – Response from the API

  • request_data (Optional[dict[str, Any]]) – Original request data

__str__()[source]

Return string representation of the error.

Return type:

str

__repr__()[source]

Return detailed representation of the error.

Return type:

str

to_dict()[source]

Convert exception to dictionary for logging/serialization.

Return type:

dict[str, Any]

Returns:

Dictionary representation of the exception

Client Errors

NepseClientError

class nepse_client.NepseClientError[source]

Bases: NepseError

Raised when client sends an invalid request (4xx errors).

This typically indicates: - Invalid parameters - Missing required fields - Malformed request data - Invalid company symbol

Example

>>> try:
...     client.getCompanyDetails("INVALID")
... except NepseClientError as e:
...     print(f"Invalid request: {e}")

Raised when client sends an invalid request (4xx errors).

This typically indicates:

  • Invalid parameters

  • Missing required fields

  • Malformed request data

  • Invalid company symbol

Example:

from nepse_client import NepseClient, NepseClientError

client = NepseClient()

try:
   # Invalid symbol
   data = client.getCompanyDetails("INVALID")
except NepseClientError as e:
   print(f"Invalid request: {e}")
__init__(message='Invalid client request', status_code=400, response_data=None, request_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

  • request_data (dict[str, Any] | None)

NepseValidationError

class nepse_client.NepseValidationError[source]

Bases: NepseError

Raised when input validation fails before making API request.

This is raised for client-side validation errors such as: - Invalid date formats - Out of range values - Missing required parameters - Invalid data types

Example

>>> try:
...     client.getCompanyPriceVolumeHistory("NABIL", start_date="invalid")
... except NepseValidationError as e:
...     print(f"Validation error: {e}")

Raised when input validation fails before making API request.

Attributes:

  • field (Optional[str]): Name of the invalid field

  • value (Optional[Any]): Invalid value provided

Example:

from nepse_client import NepseClient, NepseValidationError

client = NepseClient()

try:
   # Invalid date format
   history = client.getCompanyPriceVolumeHistory(
      "NABIL",
      start_date="invalid-date"
   )
except NepseValidationError as e:
   print(f"Validation error: {e}")
   print(f"Field: {e.field}")
__init__(message='Input validation failed', field=None, value=None)[source]

Initialize validation error.

Parameters:
  • message (str) – Error description

  • field (Optional[str]) – Name of the invalid field

  • value (Optional[Any]) – Invalid value provided

Authentication Errors

NepseAuthenticationError

class nepse_client.NepseAuthenticationError[source]

Bases: NepseError

Raised when access token has expired (401 Unauthorized).

This exception is typically handled automatically by the client, which will refresh the token and retry the request.

Note

Users usually don’t need to handle this exception directly as the client manages token refresh automatically.

Raised when access token has expired (401 Unauthorized).

Note

This exception is typically handled automatically by the client, which will refresh the token and retry the request.

Example:

from nepse_client import NepseClient, NepseAuthenticationError

client = NepseClient()

try:
   data = client.getMarketStatus()
except NepseAuthenticationError:
   # Token expired - client will auto-refresh
   print("Token expired, retrying...")
__init__(message='Authentication token expired', status_code=401, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

Server Errors

NepseServerError

class nepse_client.NepseServerError[source]

Bases: NepseError

Generic server error for 5xx status codes.

This indicates an error on the NEPSE server side. Common causes: - Internal server error (500) - Service unavailable (503) - Gateway timeout (504)

Recommended action: Retry with exponential backoff or contact support.

Generic server error for 5xx status codes.

Common causes:

  • Internal server error (500)

  • Service unavailable (503)

  • Gateway timeout (504)

Recommended action: Retry with exponential backoff.

Example:

from nepse_client import NepseClient, NepseServerError
import time

client = NepseClient()

max_retries = 3
for attempt in range(max_retries):
   try:
      data = client.getMarketStatus()
      break
   except NepseServerError as e:
      if attempt < max_retries - 1:
         wait_time = 2 ** attempt
         print(f"Server error, retrying in {wait_time}s...")
         time.sleep(wait_time)
      else:
         raise
__init__(message='Server error occurred', status_code=500, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

NepseBadGatewayError

class nepse_client.NepseBadGatewayError[source]

Bases: NepseError

Raised when server returns 502 Bad Gateway.

This typically indicates: - Server temporarily unavailable - Upstream server issues - Network problems between servers

Recommended action: Retry the request after a short delay.

Raised when server returns 502 Bad Gateway.

This typically indicates:

  • Server temporarily unavailable

  • Upstream server issues

  • Network problems between servers

Recommended action: Retry the request after a short delay.

__init__(message='Bad Gateway - Server temporarily unavailable', status_code=502, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int)

  • response_data (Any | None)

Network Errors

NepseNetworkError

class nepse_client.NepseNetworkError[source]

Bases: NepseError

Raised for general network or unexpected HTTP issues.

This covers: - Connection timeouts - DNS resolution failures - SSL/TLS errors - Unexpected response formats - Network interruptions

Recommended action: Check network connectivity and retry.

Raised for general network or unexpected HTTP issues.

This covers:

  • Connection timeouts

  • DNS resolution failures

  • SSL/TLS errors

  • Unexpected response formats

  • Network interruptions

Example:

from nepse_client import NepseClient, NepseNetworkError

client = NepseClient()

try:
   data = client.getMarketStatus()
except NepseNetworkError as e:
   print(f"Network error: {e}")
   print("Check your internet connection")
__init__(message='Network error occurred', status_code=None, response_data=None)[source]

Initialize the exception with a default message.

Parameters:
  • message (str)

  • status_code (int | None)

  • response_data (Any | None)

NepseConnectionError

class nepse_client.NepseConnectionError[source]

Bases: NepseError

Raised when connection to NEPSE server fails.

This is different from NepseNetworkError as it specifically indicates inability to establish a connection.

Raised when connection to NEPSE server fails.

__init__(message='Failed to connect to NEPSE server')[source]

Initialize the exception with a default message.

Parameters:

message (str)

NepseTimeoutError

class nepse_client.NepseTimeoutError[source]

Bases: NepseError

Raised when request times out.

This occurs when the server doesn’t respond within the specified timeout period.

timeout

Timeout value in seconds

Raised when request times out.

Attributes:

  • timeout (Optional[float]): Timeout value in seconds

Example:

from nepse_client import NepseClient, NepseTimeoutError

# Set custom timeout
client = NepseClient(timeout=30.0)

try:
   data = client.getMarketStatus()
except NepseTimeoutError as e:
   print(f"Request timed out after {e.timeout}s")
__init__(message='Request timeout', timeout=None)[source]

Initialize timeout error.

Parameters:
  • message (str) – Error description

  • timeout (Optional[float]) – Timeout value in seconds

Rate Limiting

NepseRateLimitError

class nepse_client.NepseRateLimitError[source]

Bases: NepseError

Raised when API rate limit is exceeded (429 Too Many Requests).

retry_after

Seconds to wait before retrying (if provided by server)

Raised when API rate limit is exceeded (429 Too Many Requests).

Attributes:

  • retry_after (Optional[int]): Seconds to wait before retrying

Example:

from nepse_client import NepseClient, NepseRateLimitError
import time

client = NepseClient()

try:
   data = client.getMarketStatus()
except NepseRateLimitError as e:
   if e.retry_after:
      print(f"Rate limited. Retry after {e.retry_after}s")
      time.sleep(e.retry_after)
      # Retry request
   else:
      print("Rate limited. Please try again later")
__init__(message='Rate limit exceeded', status_code=429, retry_after=None)[source]

Initialize rate limit error.

Parameters:
  • message (str) – Error description

  • status_code (int) – HTTP status code

  • retry_after (Optional[int]) – Seconds to wait before retry

Data Errors

NepseDataNotFoundError

class nepse_client.NepseDataNotFoundError[source]

Bases: NepseError

Raised when requested data is not found.

This is used when: - Company symbol doesn’t exist - No data available for requested date - Empty result sets

Example

>>> try:
...     client.getFloorSheetOf("INVALID", "2024-01-01")
... except NepseDataNotFoundError as e:
...     print(f"Data not found: {e}")

Raised when requested data is not found.

This is used when:

  • Company symbol doesn’t exist

  • No data available for requested date

  • Empty result sets

Attributes:

  • resource (Optional[str]): Resource that was not found

Example:

from nepse_client import NepseClient, NepseDataNotFoundError

client = NepseClient()

try:
   data = client.getFloorSheetOf("INVALID", "2024-01-01")
except NepseDataNotFoundError as e:
   print(f"Data not found: {e.resource}")
__init__(message='Requested data not found', resource=None)[source]

Initialize data not found error.

Parameters:
  • message (str) – Error description

  • resource (Optional[str]) – Resource that was not found

Configuration Errors

NepseConfigurationError

class nepse_client.NepseConfigurationError[source]

Bases: NepseError

Raised when there’s an issue with client configuration.

This includes: - Missing required configuration files - Invalid configuration values - Corrupted data files

Raised when there’s an issue with client configuration.

This includes:

  • Missing required configuration files

  • Invalid configuration values

  • Corrupted data files

__init__(message='Configuration error')[source]

Initialize the exception with a default message.

Parameters:

message (str)

Error Handling Best Practices

Catch Specific Exceptions

Always catch specific exceptions before general ones:

from nepse_client import (
   NepseClient,
   NepseError,
   NepseServerError,
   NepseAuthenticationError,
   NepseRateLimitError
)

client = NepseClient()

try:
   data = client.getMarketStatus()
except NepseAuthenticationError:
   # Handle authentication errors
   print("Authentication failed")
except NepseRateLimitError as e:
   # Handle rate limiting
   if e.retry_after:
      time.sleep(e.retry_after)
except NepseServerError:
   # Handle server errors
   print("Server error - try again later")
except NepseError as e:
   # Handle any other NEPSE errors
   print(f"NEPSE error: {e}")
except Exception as e:
   # Handle unexpected errors
   print(f"Unexpected error: {e}")

Retry Logic

Implement retry logic for transient errors:

import time
from nepse_client import (
   NepseClient,
   NepseServerError,
   NepseNetworkError
)

def fetch_with_retry(func, max_retries=3):
   for attempt in range(max_retries):
      try:
         return func()
      except (NepseServerError, NepseNetworkError) as e:
         if attempt < max_retries - 1:
               wait_time = 2 ** attempt
               print(f"Attempt {attempt + 1} failed, retrying in {wait_time}s...")
               time.sleep(wait_time)
         else:
               raise

client = NepseClient()
data = fetch_with_retry(client.getMarketStatus)

Logging Errors

Log errors for debugging:

import logging
from nepse_client import NepseClient, NepseError

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

client = NepseClient()

try:
    data = client.getMarketStatus()
except NepseError as e:
    logger.error(f"NEPSE error: {e}", exc_info=True)
    # exc_info=True includes full traceback

Graceful Degradation

Provide fallback behavior:

from nepse_client import NepseClient, NepseError

client = NepseClient()

try:
   companies = client.getCompanyList()
except NepseError:
   # Use cached data or default value
   companies = []
   print("Using cached data due to API error")

# Continue with application logic
print(f"Found {len(companies)} companies")