Insufficient Documentation of Error Handling Techniques

Description

Insufficient Documentation of Error Handling Techniques occurs when the documentation for a software product does not sufficiently describe the techniques that are used for error handling, exception processing, or similar mechanisms. This includes missing documentation about how errors are detected, reported, logged, and recovered from. Documentation may need to cover error handling at multiple layers including module, executable, compilable code unit, or callable levels. Without proper error handling documentation, developers and operators cannot properly handle failures, which can lead to security issues.

Risk

Insufficient error handling documentation has indirect security implications. Developers may not implement proper error handling without guidance. Operators may not know how to respond to error conditions. Security-relevant errors may not be properly logged or monitored. Error recovery procedures may not be followed. Sensitive information may leak through undocumented error messages. Exception handling may be inconsistent across the codebase. Fail-open behavior may occur when fail-secure was intended. Incident response is hindered without documented error scenarios.

Solution

Document all error types and their meanings at each layer. Specify how errors are reported (return codes, exceptions, callbacks). Document error logging requirements and what gets logged. Describe error recovery procedures and retry strategies. Specify fail-safe vs fail-secure behavior for each component. Document error codes and their security implications. Provide guidance on handling different error categories. Document exception hierarchies and when each is thrown. Include error handling examples in API documentation. Keep error documentation synchronized with implementation.

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Maintainability - Inadequate error handling documentation impairs code maintainability and makes it harder to implement consistent error handling.
OtherScope: Other

Increase Analytical Complexity - Security reviewers cannot verify proper error handling without documentation.

Example Code

Vulnerable Code

// Vulnerable: No documentation of error handling

// FILE: api_client.py
// Missing documentation for:
// - What exceptions can be thrown
// - What error codes are returned
// - How to handle different error conditions
// - What gets logged on errors
// - Retry strategies

class APIClient:
    def fetch(self, url):
        # What happens on network error?
        # What happens on timeout?
        # What happens on invalid response?
        # What gets logged?
        response = requests.get(url)
        return response.json()

    def send(self, url, data):
        # What if the request partially succeeds?
        # How do we know if data was received?
        # What errors are retryable?
        response = requests.post(url, json=data)
        return response.status_code == 200


// FILE: database.py
// No documentation about:
// - Transaction error handling
// - Connection failure recovery
// - Deadlock handling
// - Constraint violation errors

class DatabaseConnection:
    def execute(self, query, params):
        # What exceptions can this throw?
        # How are constraint violations reported?
        # Is the connection still valid after an error?
        cursor = self.conn.cursor()
        cursor.execute(query, params)
        return cursor.fetchall()


// FILE: payment_processor.py
// Critical system with undocumented error handling

class PaymentProcessor:
    def charge(self, card, amount):
        # What happens on decline?
        # What happens on fraud detection?
        # What happens on network timeout?
        # Is the charge atomic?
        # How do we check if charge went through after timeout?
        pass

    def refund(self, transaction_id, amount):
        # What if original transaction not found?
        # What if refund partially succeeds?
        # What errors are logged?
        pass

Fixed Code

// Fixed: Comprehensive error handling documentation

/*
 * ============================================================================
 * ERROR HANDLING DOCUMENTATION
 * ============================================================================
 *
 * This document describes error handling techniques used throughout the system.
 *
 * 1. ERROR CATEGORIES
 * ===================
 *
 * Category          | Action        | Retry? | Log Level | Alert?
 * ------------------|---------------|--------|-----------|--------
 * Network Timeout   | Retry         | Yes    | WARN      | After 3 retries
 * Connection Failed | Reconnect     | Yes    | WARN      | After 5 failures
 * Auth Failed       | Fail          | No     | ERROR     | Yes (potential attack)
 * Invalid Input     | Reject        | No     | WARN      | After threshold
 * Rate Limited      | Backoff       | Yes    | INFO      | No
 * Server Error      | Retry/Fail    | Maybe  | ERROR     | Yes
 * Data Corruption   | Fail+Alert    | No     | CRITICAL  | Immediate
 *
 * 2. EXCEPTION HIERARCHY
 * ======================
 *
 * BaseError
 * ├── NetworkError
 * │   ├── TimeoutError (retryable)
 * │   ├── ConnectionError (retryable)
 * │   └── SSLError (not retryable)
 * ├── AuthenticationError (not retryable)
 * │   ├── InvalidCredentialsError
 * │   └── TokenExpiredError
 * ├── ValidationError (not retryable)
 * │   ├── InvalidInputError
 * │   └── ConstraintViolationError
 * └── ServiceError
 *     ├── RateLimitError (retryable with backoff)
 *     └── InternalError (maybe retryable)
 *
 * 3. RETRY STRATEGIES
 * ===================
 *
 * Retryable errors use exponential backoff:
 * - Initial delay: 100ms
 * - Max delay: 30 seconds
 * - Max retries: 3 (configurable per operation)
 * - Backoff multiplier: 2
 * - Jitter: ±10%
 *
 * Non-retryable errors fail immediately.
 *
 * 4. LOGGING REQUIREMENTS
 * =======================
 *
 * All errors are logged with:
 * - Timestamp (ISO 8601 UTC)
 * - Error category and code
 * - Correlation ID for tracing
 * - User context (without PII)
 * - Stack trace (DEBUG level only)
 *
 * NEVER log:
 * - Passwords or credentials
 * - Full card numbers
 * - Personal identification numbers
 *
 */

// FILE: api_client.py

"""
API Client with documented error handling.

Error Handling Summary:
    - Network errors: Automatic retry with exponential backoff
    - Auth errors: Immediate failure, no retry
    - Rate limits: Automatic backoff and retry
    - Invalid responses: Logged and raised as ValidationError

Exceptions:
    NetworkError: Connection issues (timeout, connection refused)
    AuthenticationError: Invalid or expired credentials
    RateLimitError: Too many requests (auto-retry with backoff)
    ValidationError: Invalid response from server
    ServiceError: Server returned 5xx error

Logging:
    - All requests logged at DEBUG level (without auth headers)
    - Errors logged at WARN or ERROR level
    - Successful responses logged at DEBUG level
"""

class APIClient:
    """
    HTTP API client with automatic retry and error handling.

    Attributes:
        base_url: API base URL
        timeout: Request timeout in seconds (default: 30)
        max_retries: Maximum retry attempts for retryable errors (default: 3)

    Error Handling:
        Retryable errors (NetworkError, RateLimitError, 5xx responses):
            - Automatic retry with exponential backoff
            - After max_retries, raises the underlying exception

        Non-retryable errors (AuthenticationError, ValidationError, 4xx responses):
            - Immediate failure, no retry
            - Exception is raised with full error details

    Example:
        client = APIClient("https://api.example.com")
        try:
            data = client.fetch("/users/123")
        except AuthenticationError:
            # Handle auth failure - refresh token or re-authenticate
            pass
        except RateLimitError as e:
            # Handle rate limit - e.retry_after contains wait time
            pass
        except NetworkError as e:
            # Handle network failure after retries exhausted
            pass
    """

    def fetch(self, url: str) -> dict:
        """
        Fetch data from URL with automatic retry.

        Args:
            url: URL path (appended to base_url)

        Returns:
            Parsed JSON response as dictionary

        Raises:
            NetworkError: Connection failed after all retries
                - TimeoutError: Request timed out
                - ConnectionError: Cannot reach server
            AuthenticationError: Invalid or expired credentials (no retry)
            RateLimitError: Too many requests (retried automatically, raised
                           if still failing after backoff)
            ValidationError: Response is not valid JSON
            ServiceError: Server returned 5xx after all retries

        Side Effects:
            - Logs request/response at DEBUG level
            - Logs errors at WARN/ERROR level
            - Updates rate limit tracking

        Example:
            try:
                user = client.fetch("/users/123")
            except NetworkError:
                logger.error("Network unavailable, using cached data")
                user = cache.get("user_123")
        """
        pass
# Fixed: Python module with documented error handling

"""
Database Connection Module.

Error Handling Overview
=======================

This module uses a layered error handling approach:

1. Connection Errors
   - Auto-reconnect on connection loss
   - Connection pool manages retry logic
   - After 5 failures, raises DatabaseConnectionError

2. Transaction Errors
   - Deadlocks: Auto-retry up to 3 times
   - Constraint violations: Raised as IntegrityError
   - Other errors: Transaction rolled back automatically

3. Query Errors
   - Syntax errors: Raised immediately
   - Timeout: Configurable, raises QueryTimeoutError
   - Results too large: Raises ResultSetTooLargeError

Exception Hierarchy
===================

DatabaseError (base)
├── ConnectionError (retryable)
│   ├── ConnectionTimeoutError
│   └── ConnectionRefusedError
├── TransactionError
│   ├── DeadlockError (auto-retry)
│   └── IntegrityError (not retryable)
├── QueryError
│   ├── SyntaxError
│   ├── QueryTimeoutError
│   └── ResultSetTooLargeError
└── PoolExhaustedError (wait or fail)

Logging
=======

All queries logged at DEBUG level (parameterized, not with values).
Errors logged at ERROR level with query hash for correlation.
Connection events logged at INFO level.

Security Notes
==============

- Query parameters logged as placeholders only, never actual values
- Connection strings redacted in logs
- Stack traces limited in production mode
"""

class DatabaseConnection:
    """
    Database connection with documented error handling.

    Connection Management:
        - Connections validated before use (ping/select 1)
        - Automatic reconnection on connection loss
        - Connection pooling with configurable limits

    Transaction Handling:
        - Default auto-commit disabled
        - Explicit commit/rollback required
        - Automatic rollback on exception

    Error Recovery:
        - Deadlocks: Automatic retry with backoff
        - Connection loss: Automatic reconnection
        - Timeout: Transaction rolled back, connection returned to pool
    """

    def execute(
        self,
        query: str,
        params: tuple = None,
        timeout: float = 30.0
    ) -> list:
        """
        Execute a SQL query with parameters.

        Args:
            query: SQL query with parameter placeholders
            params: Query parameters (properly escaped)
            timeout: Query timeout in seconds

        Returns:
            List of result rows as dictionaries

        Raises:
            ConnectionError: Database connection failed
                Connection is automatically re-established; caller may retry.

            SyntaxError: SQL syntax error in query
                Query is invalid; fix the query before retrying.

            IntegrityError: Constraint violation (unique, foreign key, etc.)
                Transaction is rolled back. Caller should handle conflict.

            DeadlockError: Deadlock detected
                Automatically retried 3 times. Raised if still deadlocked.
                Caller should consider transaction ordering.

            QueryTimeoutError: Query exceeded timeout
                Transaction is rolled back. Consider query optimization.

        Side Effects:
            - Query logged at DEBUG (parameterized form only)
            - Errors logged at ERROR with query hash
            - Metrics updated (query count, latency, errors)

        Thread Safety:
            This method is NOT thread-safe. Each thread should use
            its own connection or use ConnectionPool.

        Example:
            try:
                users = db.execute(
                    "SELECT * FROM users WHERE status = ?",
                    ("active",)
                )
            except IntegrityError:
                logger.warning("Constraint violation, checking duplicates")
            except QueryTimeoutError:
                logger.error("Query timeout, using cached results")
        """
        pass

CVE Examples

This CWE is marked as PROHIBITED for direct CVE mapping as it represents a documentation quality concern rather than a direct security vulnerability.


  • CWE-1059: Insufficient Technical Documentation (parent)
  • CWE-1225: Documentation Issues (category member)
  • CWE-1110: Incomplete Design Documentation (related)
  • CWE-755: Improper Handling of Exceptional Conditions (related consequence)

References

  1. MITRE Corporation. "CWE-1118: Insufficient Documentation of Error Handling Techniques." https://cwe.mitre.org/data/definitions/1118.html
  2. Error Handling Best Practices in API Design
  3. Microsoft - Error Handling Documentation Guidelines