PHP Classes

How to Use a PHP Error Handling Approach that Has More Options Using the Package Hephaestus Modern and Sophisticated Error Handling for PHP 8: Handle PHP errors in several ways

Recommend this page to a friend!
  Info   Documentation   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2024-11-25 (12 days ago) RSS 2.0 feedNot enough user ratingsTotal: 12 This week: 12All time: 11,446 This week: 6Up
Version License PHP version Categories
hephaestus 1.1.0GNU General Publi...8.1Debug, Language, PHP 8
Description 

Author

This package can handle PHP errors in several ways.

It provides several classes with functions that can perform checks for error conditions and process the errors based on the function parameters.

The package introduces more error-handling tools and improvements to PHP 8.1 or later, including support for Symfony as a bundler.

Currently, the classes can:

- Handle cases when a required value is missing

- Handle cases when one or more optional values are required

It also provides a function to retry executing code that may fail up to a given number of times.

The package can process exceptions with values of error messages and descriptions read from a configuration file.

Picture of Carlos Artur Curvelo da Matos
  Performance   Level  
Name: Carlos Artur Curvelo da ... <contact>
Classes: 22 packages by
Country: Portugal Portugal
Innovation award
Innovation award
Nominee: 14x

Winner: 2x

Documentation

Hephaestus

PHP Composer

God-like error handling library for modern PHP programmers. Hephaestus provides a comprehensive set of tools for elegant error handling, combining functional programming concepts with robust exception management.

Features

  • Option Type: Rust-inspired `Some/None` type for safe handling of nullable values
  • Enhanced Exceptions: Advanced error handling with state tracking and exception history
  • Retry Mechanism: Built-in retry capabilities for transient failures
  • Symfony Integration: Seamless integration with Symfony framework (optional)
  • Type Safety: Full PHP 8.1+ type system support

Requirements

  • PHP 8.1 or higher
  • Symfony 7.1 or higher (optional, for bundle integration)

Installation

Basic Installation

composer require cmatosbc/hephaestus

Symfony Bundle Installation

  1. Install the package as shown above
  2. Register the bundle in `config/bundles.php`:
    return [
    // ...
    Hephaestus\Bundle\HephaestusBundle::class => ['all' => true],
    ];
    
  3. Configure the bundle in `config/packages/hephaestus.yaml`:
    hephaestus:
    max_retries: 3
    retry_delay: 1
    logging:
        enabled: true
        channel: 'hephaestus'
    

Core Components

Option Type

The Option type provides a safe way to handle potentially null values:

use function Hephaestus\Some;
use function Hephaestus\None;

// Basic usage
$user = Some(['name' => 'Zeus']);
$name = $user->map(fn($u) => $u['name'])
            ->getOrElse('Anonymous'); // Returns "Zeus"

// Pattern matching
$greeting = $user->match(
    some: fn($u) => "Welcome, {$u['name']}!",
    none: fn() => "Welcome, stranger!"
);

// Chaining operations
$drinking_age = Some(['name' => 'Dionysus', 'age' => 21])
    ->filter(fn($u) => $u['age'] >= 21)
    ->map(fn($u) => "{$u['name']} can drink!")
    ->getOrElse("Not old enough");

Enhanced Exception Handling

The EnhancedException class provides state tracking and exception history management:

use Hephaestus\EnhancedException;

class DatabaseException extends EnhancedException {}

try {
    throw new DatabaseException(
        "Query failed",
        0,
        new \PDOException("Connection lost")
    );
} catch (DatabaseException $e) {
    // Track exception history
    $history = $e->getExceptionHistory();
    $lastError = $e->getLastException();
    
    // Add context
    $e->saveState(['query' => 'SELECT * FROM users'])
      ->addToHistory(new \Exception("Additional context"));
    
    // Type-specific error handling
    if ($e->hasExceptionOfType(\PDOException::class)) {
        $pdoErrors = $e->getExceptionsOfType(\PDOException::class);
    }
}

Retry Mechanism

Built-in retry capabilities for handling transient failures:

use function Hephaestus\withRetryBeforeFailing;

// Retry an operation up to 3 times
$result = withRetryBeforeFailing(3)(function() {
    return file_get_contents('https://api.example.com/data');
});

// Combine with Option type for safer error handling
function fetchDataSafely($url): Option {
    return withRetryBeforeFailing(3)(function() use ($url) {
        $response = file_get_contents($url);
        return $response === false ? None() : Some(json_decode($response, true));
    });
}

$data = fetchDataSafely('https://api.example.com/data')
    ->map(fn($d) => $d['value'])
    ->getOrElse('default');

Pattern-Matched Exception Handling

Hephaestus provides a powerful pattern-matched exception handling system that allows you to define custom error messages and descriptions for different exception types.

Setting Up Exception Patterns

First, generate the exception patterns file using the hephaestus command:

# Generate exceptions.json with all available exception classes
./vendor/bin/hephaestus init

This will create an exceptions.json file in your project root with the following structure:

{
    "RuntimeException": {
        "message": "Runtime Error",
        "description": "An error that can only be detected during program execution."
    },
    "InvalidArgumentException": {
        "message": "Invalid Input",
        "description": "The provided argument is not valid for this operation."
    }
}

You can customize the messages and descriptions in this file to match your application's needs.

Using Pattern-Matched Exception Handling

The withMatchedExceptions() function provides a clean way to handle exceptions using the patterns defined in your exceptions.json file:

use function Hephaestus\withMatchedExceptions;

// Basic usage
$result = withMatchedExceptions(
    fn() => $connection->connect()
);

// With a custom patterns file
$result = withMatchedExceptions(
    fn() => $service->riskyOperation(),
    __DIR__ . '/custom/patterns.json'
);

// With a custom default message
$result = withMatchedExceptions(
    fn() => $api->request(),
    null,
    'API Error'
);

// Using array callable
$result = withMatchedExceptions(
    [$service, 'method']
);

When an exception occurs, it will be matched against the patterns in your exceptions.json file, and a formatted error message will be returned:

// If a DatabaseException occurs:
"Database Error: Failed to connect to localhost"

Description: A database connection or operation error occurred. Check your database credentials and ensure the database server is running.

Command Line Tool

The hephaestus command line tool helps you manage your exception patterns:

# Generate patterns file
./vendor/bin/hephaestus init

# View available commands
./vendor/bin/hephaestus list

Command Options

  • `init`: Generates the `exceptions.json` file - Scans your project for exception classes - Creates human-readable messages from class names - Extracts descriptions from class docblocks when available - Prompts before overwriting existing file

Customizing Exception Patterns

You can customize your exceptions.json file to provide more specific messages and descriptions:

{
    "App\\Exceptions\\DatabaseException": {
        "message": "Database Connection Failed",
        "description": "Unable to establish a connection to the database. Please check your database configuration and ensure the database server is running."
    },
    "App\\Exceptions\\ValidationException": {
        "message": "Invalid Input Data",
        "description": "The provided data failed validation. Please check your input and try again."
    }
}

Error Message Format

The error messages returned by withMatchedExceptions() follow this format:

[Custom Message]: [Exception Message]

Description: [Custom Description]

For unmatched exceptions, a default message is used:

Unexpected error: [Exception Message]

Description: A general error has occurred.

Symfony Integration

Option Factory Service

The bundle provides an OptionFactory service with built-in retry capabilities:

use Hephaestus\Bundle\Service\OptionFactory;

class UserService
{
    public function __construct(private OptionFactory $optionFactory)
    {}

    public function findUser(int $id): Option
    {
        return $this->optionFactory->fromCallable(
            fn() => $this->userRepository->find($id)
        );
    }
}

HTTP-Aware Exceptions

The SymfonyEnhancedException class provides HTTP-specific error handling:

use Hephaestus\Bundle\Exception\SymfonyEnhancedException;

class UserNotFoundException extends SymfonyEnhancedException
{
    public function __construct(int $userId)
    {
        parent::__construct(
            "User not found",
            Response::HTTP_NOT_FOUND
        );
        $this->saveState(['user_id' => $userId]);
    }
}

class UserController
{
    public function show(int $id): Response
    {
        return $this->optionFactory
            ->fromCallable(fn() => $this->userRepository->find($id))
            ->match(
                some: fn($user) => $this->json($user),
                none: fn() => throw new UserNotFoundException($id)
            );
    }
}

Key Benefits

  • Type Safety: Leverage PHP 8.1+ type system for safer code
  • Functional Approach: Chain operations with map, filter, and match
  • Explicit Error Handling: Make potential failures visible in method signatures
  • State Tracking: Capture and maintain error context and history
  • Resilient Operations: Built-in retry mechanism for transient failures
  • Framework Integration: Seamless Symfony integration when needed

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under the GNU General Public License v3.0 or later - see the LICENSE file for details. This means you are free to use, modify, and distribute this software, but any modifications must also be released under the GPL-3.0-or-later license.


  Files folder image Files (27)  
File Role Description
Files folder image.github (1 directory)
Files folder imagebin (1 file)
Files folder imageBundle (1 file, 4 directories)
Files folder imagesrc (7 files, 1 directory)
Files folder imagetests (5 files, 1 directory)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files (27)  /  .github  
File Role Description
Files folder imageworkflows (1 file)

  Files folder image Files (27)  /  .github  /  workflows  
File Role Description
  Accessible without login Plain text file main.yml Data Auxiliary data

  Files folder image Files (27)  /  bin  
File Role Description
  Accessible without login Plain text file hephaestus Example Example script

  Files folder image Files (27)  /  Bundle  
File Role Description
Files folder imageDependencyInjection (2 files)
Files folder imageException (1 file)
Files folder imageResources (1 directory)
Files folder imageService (2 files)
  Plain text file HephaestusBundle.php Class Class source

  Files folder image Files (27)  /  Bundle  /  DependencyInjection  
File Role Description
  Plain text file Configuration.php Class Class source
  Plain text file HephaestusExtension.php Class Class source

  Files folder image Files (27)  /  Bundle  /  Exception  
File Role Description
  Plain text file SymfonyEnhancedException.php Class Class source

  Files folder image Files (27)  /  Bundle  /  Resources  
File Role Description
Files folder imageconfig (1 file)

  Files folder image Files (27)  /  Bundle  /  Resources  /  config  
File Role Description
  Accessible without login Plain text file services.yaml Data Auxiliary data

  Files folder image Files (27)  /  Bundle  /  Service  
File Role Description
  Plain text file ExceptionHandler.php Class Class source
  Plain text file OptionFactory.php Class Class source

  Files folder image Files (27)  /  src  
File Role Description
Files folder imageConsole (1 file)
  Plain text file CheckedException.php Class Class source
  Plain text file EnhancedException.php Class Class source
  Accessible without login Plain text file functions.php Example Example script
  Plain text file None.php Class Class source
  Plain text file Option.php Class Class source
  Plain text file Some.php Class Class source
  Plain text file SomeNoneException.php Class Class source

  Files folder image Files (27)  /  src  /  Console  
File Role Description
  Plain text file InitCommand.php Class Class source

  Files folder image Files (27)  /  tests  
File Role Description
Files folder imageConsole (1 file)
  Plain text file CheckedExceptionTest.php Class Class source
  Plain text file EnhancedExceptionTest.php Class Class source
  Plain text file OptionTest.php Class Class source
  Plain text file RetryTest.php Class Class source
  Plain text file WithMatchedExceptionsTest.php Class Class source

  Files folder image Files (27)  /  tests  /  Console  
File Role Description
  Plain text file InitCommandTest.php Class Class source

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
 Version Control Unique User Downloads Download Rankings  
 100%
Total:12
This week:12
All time:11,446
This week:6Up