Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Codes

php-sqlx exceptions include error codes that help identify the type of error.

Error Code Constants

Error codes are defined as constants on SqlxException:

use Sqlx\Exceptions\SqlxException;

SqlxException::GENERAL          // 0 - General/unknown error
SqlxException::CONNECTION       // 1 - Connection failed
SqlxException::QUERY            // 2 - Query execution failed
SqlxException::TRANSACTION      // 3 - Transaction error
SqlxException::PARSE            // 4 - SQL parsing error
SqlxException::PARAMETER        // 5 - Parameter binding error
SqlxException::CONFIGURATION    // 6 - Configuration error
SqlxException::VALIDATION       // 7 - Validation error
SqlxException::NOT_PERMITTED    // 8 - Operation not allowed
SqlxException::TIMEOUT          // 9 - Operation timed out
SqlxException::POOL_EXHAUSTED   // 10 - Connection pool exhausted

Using Error Codes

use Sqlx\Exceptions\SqlxException;

try {
    $driver->queryRow($sql, $params);
} catch (SqlxException $e) {
    switch ($e->getCode()) {
        case SqlxException::CONNECTION:
            // Database unavailable
            break;
        case SqlxException::QUERY:
            // Query failed
            break;
        case SqlxException::TIMEOUT:
            // Operation too slow
            break;
        default:
            // Other error
    }
}

Code Reference

GENERAL (0)

Unspecified error. Check the message for details.

// Rare - most errors have specific codes

CONNECTION (1)

Connection to database failed.

// Network error
// "Connection error: Failed to connect to server"

// Authentication failure
// "Connection error: password authentication failed for user 'myuser'"

// SSL error
// "Connection error: SSL connection required"

QUERY (2)

Query execution failed.

// Table doesn't exist
// "Query error: relation \"nonexistent\" does not exist"

// Column doesn't exist
// "Query error: column \"invalid_col\" does not exist"

// Constraint violation
// "Query error: duplicate key value violates unique constraint"

// Permission denied
// "Query error: permission denied for table users"

TRANSACTION (3)

Transaction operation failed.

// Deadlock
// "Transaction error: deadlock detected"

// Serialization failure
// "Transaction error: could not serialize access"

// Already in transaction
// "Transaction error: there is already a transaction in progress"

PARSE (4)

SQL parsing failed (before sending to database).

// Invalid conditional block
// "Parse error: unclosed conditional block"

// Invalid placeholder
// "Parse error: unknown placeholder type '?x'"

PARAMETER (5)

Parameter binding failed.

// Type mismatch
// "Parameter error: expected integer, got string 'abc'"

// Wrong count
// "Parameter error: expected 3 parameters, got 2"

// Missing named parameter
// "Parameter error: missing required parameter 'user_id'"

CONFIGURATION (6)

Configuration error.

// Missing URL
// "Configuration error: OPT_URL is required"

// Invalid option
// "Configuration error: invalid value for OPT_MAX_CONNECTIONS"

VALIDATION (7)

Input validation failed.

// Invalid identifier
// "Validation error: invalid table name"

NOT_PERMITTED (8)

Operation not allowed.

// Write on read-only
// "Not permitted: write operations disabled on read-only connection"

TIMEOUT (9)

Operation timed out.

// Query timeout
// "Timeout: query exceeded maximum execution time"

// Statement timeout
// "Timeout: canceling statement due to statement timeout"

POOL_EXHAUSTED (10)

Connection pool is full.

// All connections busy
// "Pool exhausted: timed out waiting for connection"

Database-Specific Error Information

The original database error is often included in the message:

try {
    $driver->execute("INSERT INTO users (email) VALUES (?)", ['duplicate@example.com']);
} catch (QueryException $e) {
    // PostgreSQL
    // "Query error: duplicate key value violates unique constraint \"users_email_key\""

    // MySQL
    // "Query error: Duplicate entry 'duplicate@example.com' for key 'users.email'"

    // MSSQL
    // "Query error: Violation of UNIQUE KEY constraint 'UQ_users_email'"
}

Programmatic Error Handling

By Exception Type

use Sqlx\Exceptions\{
    ConnectionException,
    QueryException,
    TimeoutException,
    PoolExhaustedException
};

try {
    $result = $driver->queryAll($sql, $params);
} catch (ConnectionException $e) {
    // Retry with backoff or fail
} catch (TimeoutException $e) {
    // Cancel or increase timeout
} catch (PoolExhaustedException $e) {
    // Wait and retry
} catch (QueryException $e) {
    // Log and report error
}

By Error Code

try {
    $result = $driver->queryAll($sql, $params);
} catch (SqlxException $e) {
    if (in_array($e->getCode(), [
        SqlxException::CONNECTION,
        SqlxException::TIMEOUT,
        SqlxException::POOL_EXHAUSTED,
    ])) {
        // Infrastructure issue - retry or fail gracefully
        return $this->handleInfrastructureError($e);
    }

    if ($e->getCode() === SqlxException::QUERY) {
        // Application bug - log details
        return $this->handleQueryError($e);
    }

    throw $e;
}

By Transient Flag

try {
    $result = $driver->queryAll($sql, $params);
} catch (SqlxException $e) {
    if ($e->isTransient()) {
        // Temporary issue - can retry
        // (deadlock, connection lost, timeout)
    } else {
        // Permanent issue - don't retry
        // (syntax error, permission denied)
    }
}

Logging Recommendations

Include relevant context in error logs:

try {
    $result = $driver->execute($sql, $params);
} catch (SqlxException $e) {
    $this->logger->error('Database operation failed', [
        'error_code' => $e->getCode(),
        'error_name' => $this->getErrorName($e->getCode()),
        'message' => $e->getMessage(),
        'sql' => $e->getSql(),
        'is_transient' => $e->isTransient(),
        'context' => [
            'user_id' => $currentUserId,
            'request_id' => $requestId,
        ],
    ]);
}

private function getErrorName(int $code): string
{
    return match($code) {
        SqlxException::GENERAL => 'GENERAL',
        SqlxException::CONNECTION => 'CONNECTION',
        SqlxException::QUERY => 'QUERY',
        SqlxException::TRANSACTION => 'TRANSACTION',
        SqlxException::PARSE => 'PARSE',
        SqlxException::PARAMETER => 'PARAMETER',
        SqlxException::CONFIGURATION => 'CONFIGURATION',
        SqlxException::VALIDATION => 'VALIDATION',
        SqlxException::NOT_PERMITTED => 'NOT_PERMITTED',
        SqlxException::TIMEOUT => 'TIMEOUT',
        SqlxException::POOL_EXHAUSTED => 'POOL_EXHAUSTED',
        default => 'UNKNOWN',
    };
}