Exception Hierarchy#

All HFortix exceptions inherit from FortinetError.

Exception Classes#

FortiOS-Specific Exceptions FortiOS error codes and product-specific exception handling

exception hfortix_core.exceptions.FortinetError[source]#

Bases: Exception

Base exception for all Fortinet API errors

exception hfortix_core.exceptions.APIError[source]#

Bases: FortinetError

Generic API error with optional metadata

message#

Error message

http_status#

HTTP status code (e.g., 400, 404, 500)

error_code#

FortiOS internal error code (e.g., -5, -3)

response#

Full API response dict

endpoint#

API endpoint path (e.g., ‘/api/v2/cmdb/firewall/policy’)

method#

HTTP method (GET, POST, PUT, DELETE)

params#

Request parameters (sanitized)

hint#

Helpful suggestion for resolving the error

request_id#

Unique identifier for this request

timestamp#

ISO 8601 timestamp when error occurred

__init__(message, http_status=None, error_code=None, response=None, endpoint=None, method=None, params=None, hint=None, request_id=None)[source]#
__str__()[source]#

Format error with full context for better debugging

Return type:

str

__repr__()[source]#

Developer-friendly representation for debugging

Return type:

str

exception hfortix_core.exceptions.AuthenticationError[source]#

Bases: FortinetError

HTTP 401 - Authentication failed (invalid credentials)

exception hfortix_core.exceptions.AuthorizationError[source]#

Bases: FortinetError

HTTP 403 - Authorization failed (insufficient permissions)

exception hfortix_core.exceptions.RetryableError[source]#

Bases: APIError

Base exception for errors that should trigger automatic retry

These errors are typically transient and may succeed on retry: - Rate limiting (429) - Service unavailable (503) - Timeouts - Circuit breaker open

exception hfortix_core.exceptions.NonRetryableError[source]#

Bases: APIError

Base exception for errors that should NOT be retried

These errors indicate client-side mistakes or permanent failures: - Bad request (400) - Resource not found (404) - Duplicate entry - Entry in use - Permission denied

exception hfortix_core.exceptions.ConfigurationError[source]#

Bases: FortinetError

Raised when FortiOS instance is misconfigured

Examples: - Both token and username/password provided - Missing required authentication - Invalid parameter combinations

exception hfortix_core.exceptions.VDOMError[source]#

Bases: FortinetError

Raised when VDOM operation fails or VDOM doesn’t exist

vdom#

The VDOM name that caused the error

Parameters:
__init__(message, vdom)[source]#
Parameters:
exception hfortix_core.exceptions.OperationNotSupportedError[source]#

Bases: FortinetError

Raised when attempting unsupported operation on endpoint

operation#

The operation that was attempted (e.g., ‘DELETE’)

endpoint#

The endpoint that doesn’t support it

Parameters:
  • message (str)

  • operation (str)

  • endpoint (str)

__init__(message, operation, endpoint)[source]#
Parameters:
  • message (str)

  • operation (str)

  • endpoint (str)

exception hfortix_core.exceptions.ReadOnlyModeError[source]#

Bases: FortinetError

Operation blocked by read-only mode

Raised when attempting POST/PUT/DELETE operations with read_only=True. This is a client-side block to prevent accidental writes in safe mode.

exception hfortix_core.exceptions.BadRequestError[source]#

Bases: NonRetryableError

HTTP 400 - Bad Request

__init__(message='Bad request', **kwargs)[source]#
exception hfortix_core.exceptions.ResourceNotFoundError[source]#

Bases: NonRetryableError

HTTP 404 - Resource not found

__init__(message='Resource not found', **kwargs)[source]#
suggest_recovery()[source]#

Suggest how to recover from this error

Return type:

str

exception hfortix_core.exceptions.MethodNotAllowedError[source]#

Bases: NonRetryableError

HTTP 405 - Method not allowed

__init__(message='Method not allowed', **kwargs)[source]#
exception hfortix_core.exceptions.RateLimitError[source]#

Bases: RetryableError

HTTP 429 - Rate limit exceeded

__init__(message='Rate limit exceeded', **kwargs)[source]#
exception hfortix_core.exceptions.ServerError[source]#

Bases: RetryableError

HTTP 500 - Internal server error

__init__(message='Internal server error', **kwargs)[source]#
exception hfortix_core.exceptions.ServiceUnavailableError[source]#

Bases: RetryableError

HTTP 503 - Service temporarily unavailable

__init__(message='Service temporarily unavailable', **kwargs)[source]#
exception hfortix_core.exceptions.CircuitBreakerOpenError[source]#

Bases: RetryableError

Circuit breaker is open - service appears to be down

__init__(message='Circuit breaker is open', **kwargs)[source]#
exception hfortix_core.exceptions.TimeoutError[source]#

Bases: RetryableError

Request timed out

__init__(message='Request timed out', **kwargs)[source]#
exception hfortix_core.exceptions.DuplicateEntryError[source]#

Bases: NonRetryableError

Duplicate entry exists (error code -5, -15, -100, etc.)

__init__(message='A duplicate entry already exists', **kwargs)[source]#
suggest_recovery()[source]#

Suggest how to recover from this error

Return type:

str

exception hfortix_core.exceptions.EntryInUseError[source]#

Bases: NonRetryableError

Entry cannot be deleted because it’s in use (error code -23, -94, -95, etc.)

__init__(message='Entry is in use and cannot be deleted', **kwargs)[source]#
suggest_recovery()[source]#

Suggest how to recover from this error

Return type:

str

exception hfortix_core.exceptions.InvalidValueError[source]#

Bases: NonRetryableError

Invalid value provided (error code -651, -1, -50, etc.)

__init__(message='Input value is invalid', **kwargs)[source]#
exception hfortix_core.exceptions.PermissionDeniedError[source]#

Bases: NonRetryableError

Permission denied, insufficient privileges (error code -14, -37)

__init__(message='Permission denied. Insufficient privileges.', **kwargs)[source]#
hfortix_core.exceptions.get_error_description(error_code)[source]#

Get human-readable description for FortiOS error code

Parameters:

error_code (int) – FortiOS error code

Returns:

Error description or “Unknown error”

Return type:

str

Examples

>>> get_error_description(-5)
'A duplicate entry already exists'
>>> get_error_description(-651)
'Input value is invalid'
hfortix_core.exceptions.get_http_status_description(status_code)[source]#

Get human-readable description for HTTP status code

Parameters:

status_code (int) – HTTP status code

Returns:

Status description or “Unknown status code”

Return type:

str

hfortix_core.exceptions.raise_for_status(response, endpoint=None, method=None, params=None)[source]#

Raise appropriate exception based on FortiOS API response

Parameters:
  • response (dict) – API response dictionary

  • endpoint (str) – Optional API endpoint for better error context

  • method (str) – Optional HTTP method (GET, POST, PUT, DELETE)

  • params (dict) – Optional request parameters (will be sanitized)

Raises:

APIError – If response indicates an error

Return type:

None

Examples

>>> response = {'status': 'error', 'http_status': 404, 'error': -3}
>>> raise_for_status(
...     response,
...     endpoint='/api/v2/cmdb/firewall/address',
...     method='GET'
... )
# Raises ResourceNotFoundError with helpful context and tip
hfortix_core.exceptions.is_retryable_error(error)[source]#

Check if error should trigger automatic retry

Parameters:

error (Exception) – Exception to check

Return type:

bool

Returns:

True if error is retryable, False otherwise

Example

>>> try:
...     fgt.api.cmdb.firewall.policy.get()
... except Exception as e:
...     if is_retryable_error(e):
...         time.sleep(5)
...         # retry logic here
hfortix_core.exceptions.get_retry_delay(error, attempt, base_delay=1.0, max_delay=60.0)[source]#

Calculate appropriate retry delay based on error type and attempt number

Parameters:
  • error (Exception) – Exception that occurred

  • attempt (int) – Retry attempt number (1, 2, 3, …)

  • base_delay (float, default: 1.0) – Base delay in seconds (default: 1.0)

  • max_delay (float, default: 60.0) – Maximum delay in seconds (default: 60.0)

Return type:

float

Returns:

Recommended delay in seconds

Example

>>> for attempt in range(1, 4):
...     try:
...         result = fgt.api.cmdb.firewall.policy.get()
...         break
...     except Exception as e:
...         if is_retryable_error(e):
...             delay = get_retry_delay(e, attempt)
...             time.sleep(delay)
...         else:
...             raise

Exception Hierarchy#

FortinetError (Base exception)
├── APIError (Base for all API errors)
│   ├── HTTPError (Base for HTTP errors)
│   │   ├── BadRequestError (400)
│   │   ├── UnauthorizedError (401)
│   │   ├── ForbiddenError (403)
│   │   ├── ResourceNotFoundError (404)
│   │   ├── MethodNotAllowedError (405)
│   │   ├── RateLimitError (429)
│   │   └── ServerError (500+)
│   ├── DuplicateEntryError (FortiOS: object exists)
│   ├── EntryInUseError (FortiOS: object in use)
│   └── ValidationError (Invalid input)
├── ConnectionError (Network/connection issues)
├── TimeoutError (Request timeout)
└── ConfigurationError (Invalid configuration)

Usage Examples#

Basic Exception Handling#

from hfortix_fortios import FortiOS
from hfortix_core import (
    APIError,
    ResourceNotFoundError,
    DuplicateEntryError
)

fgt = FortiOS(host='192.168.1.99', token='your-token')

try:
    fgt.api.cmdb.firewall.address.post(
        name='test-server',
        subnet='10.0.0.1/32'
    )
except DuplicateEntryError:
    print("Address already exists!")
except ValidationError as e:
    print(f"Invalid input: {e.message}")
except APIError as e:
    print(f"API error: {e.message}")

Specific HTTP Errors#

from hfortix_core import (
    ResourceNotFoundError,
    UnauthorizedError,
    ForbiddenError
)

try:
    result = fgt.api.cmdb.firewall.address.get(name='missing')
except ResourceNotFoundError:
    print("Address not found")
except UnauthorizedError:
    print("Invalid credentials")
except ForbiddenError:
    print("Insufficient permissions")

FortiOS-Specific Errors#

from hfortix_core import DuplicateEntryError, EntryInUseError

# Handle duplicate entries
try:
    fgt.api.cmdb.firewall.address.post(name='existing', subnet='10.0.0.1/32')
except DuplicateEntryError:
    # Update instead
    fgt.api.cmdb.firewall.address.put(name='existing', comment='Updated')

# Handle in-use objects
try:
    fgt.api.cmdb.firewall.address.delete(name='in-use-address')
except EntryInUseError as e:
    print(f"Cannot delete: {e.message}")
    print("Remove from policies first")

Connection and Timeout Errors#

from hfortix_core import ConnectionError, TimeoutError

try:
    fgt = FortiOS(
        host='unreachable-host',
        token='token',
        connect_timeout=5.0
    )
    result = fgt.api.monitor.system.status.get()
except ConnectionError:
    print("Cannot connect to FortiGate")
except TimeoutError:
    print("Request timed out")

Error Attributes#

All exceptions include helpful attributes:

try:
    result = fgt.api.cmdb.firewall.address.post(
        name='test',
        subnet='10.0.0.1/32'
    )
except APIError as e:
    print(f"Message: {e.message}")
    print(f"Error Code: {e.error_code}")
    print(f"HTTP Status: {e.http_status}")
    print(f"Details: {e.details}")

See Also#

  • /core/user-guide/error-handling - Comprehensive error handling guide

  • /core/api-reference/client - FortiOS client reference

  • Core Package API Reference - Core package reference