Luminova Framework

PHP Luminova: Abstract Base Exception for Application

Last updated: 2025-08-27 18:29:50

The AppException class is Luminova’s base for handling errors, providing a consistent way to catch, log, and respond to unexpected issues using built-in exceptions and the Tripwire error system.

The AppException class is the foundation of Luminova's exception classes. Exception handling is essential for maintaining application stability and ensuring a smooth user experience when unexpected issues occur.

Luminova provides a rich collection of exception classes along with custom helper methods, all working seamlessly with the Core Error Monitoring System. Together, they give you the tools to detect problems, record them, and present meaningful feedback without leaving your users confused.

This guide explains how Luminova organizes its exceptions, how you can use them in your projects, and how they help keep your application resilient. By understanding and using these classes, you can ensure that errors are caught, logged, and handled cleanly, keeping disruptions to a minimum.

For a complete list of built-in exception codes, see Exception and Error Codes documentation.


Examples

Luminova ships with both general-purpose exceptions such as ErrorException and specialized ones like DatabaseException and Http\ClientException. This guide shows you how to throw and catch these exceptions in real projects, and how to customize them when your application has unique needs.

Extending the AppException Class

When you create your own exception by extending AppException, you gain access to all of its core features automatically. This makes it simple to build exceptions that fit your project while keeping consistent behavior with the rest of the framework.

// /app/Exceptions/CustomException.php

/**
 * Custom exception class that extends Luminova AppException.
 *
 * @template T
 * @extends Luminova\Exceptions\AppException<T>
 */
namespace App\Exceptions;

use Luminova\Exceptions\AppException;
use Throwable;

class CustomException extends AppException
{
    public function __construct(
        string $message,
        string|int $code = 0,
        ?Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
    }
}

Creating a Custom Exception Without AppException

You can define your own exception class without extending Luminova’s AppException. In this case, you should implement the Luminova\Interface\ExceptionInterface to ensure compatibility with Luminova’s error system.

// /app/Exceptions/CustomException.php

/**
 * Custom class that implements the Luminova ExceptionInterface.
 *
 * @template \T
 * @implements \T<Luminova\Interface\ExceptionInterface>
 */
namespace App\Exceptions;

use Luminova\Interface\ExceptionInterface;
use \Exception;
use \Throwable;

class CustomException extends Exception implements ExceptionInterface
{
    public function __construct(
        string $message,
        string|int $code = 0,
        ?Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
    }

    // You can add your own methods or properties here as needed
}

NoteWhen doing this, remember that exception codes may be either strings or integers, so you need to account for both.


Throwing Exceptions

In luminova, you can throw an exception in traditional way using throw statement and new Object or using the throwException method to throw and exception gracefully.

The usual way

You can throw an exception directly whenever something goes wrong:

use Luminova\Exceptions\RuntimeException;

throw new RuntimeException('Invalid configuration file.');

Graceful throwing based on environment

Luminova provides helper methods such as throwException to handle errors differently depending on whether the app is running in production or development. In production, non-fatal errors are logged quietly, while fatal errors show only a basic “something went wrong” message without exposing sensitive details.

use Luminova\Exceptions\RuntimeException;

RuntimeException::throwException('Invalid configuration file.');

Throwing an error when input is missing

use Luminova\Exceptions\Code;
use Luminova\Exceptions\ErrorException;

function loginAccount(string $username, string $password) 
{
    if (!$username || !$password) {
        throw new ErrorException(
            'Username and password are required.',
            Code::INVALID_ARGUMENTS
        );
    }
}

Throwing as Another Exception Type

You can also rethrow errors as a different exception type. This is helpful when you need to unify how different errors are handled in your application.

use Luminova\Exceptions\ErrorException;
use Luminova\Exceptions\AppException;
use Luminova\Exceptions\RuntimeException;

// Convert a generic Error into a RuntimeException
AppException::throwAs(
    new Error('An error occurred'),
    RuntimeException::class
);

// Convert a generic Error into an ErrorException
ErrorException::throwAs(new Error('An error occurred'));

Catching Exceptions

Exceptions are usually handle using try, catch and finally blocks. This lets you intercept problems and respond appropriately rather than letting the application crash.

For example, you might show a user-friendly message in production while logging the full details for developers to review later.

Handling an Exception Code

You can catch exceptions thrown by the (e.g, loginAccount) function using a try-catch block. Below is an example of how to handle different types of exceptions based on their error codes.

use Luminova\Exceptions\Code;

try {
    $user = loginAccount($username, $password);
} catch (Throwable $e) {
    // Handle errors based on the error code.

    if ($e->isCode(Code::INVALID_ARGUMENTS)) {
        echo "Username and password are required.";
    } elseif ($e->isCode(Code::VALUE_FORBIDDEN)) {
        echo "Access to the requested value is forbidden.";
    } else {
        echo "Error: " . $e->getMessage();
    }
}

Handling a Specific Exception Type

You can catch a specific exception type, such as ErrorException, for more granular error handling.

try {
    $user = loginAccount($username, $password);
} catch (Luminova\Exceptions\ErrorException $e) {
    // Handle specific errors here.
    echo $e->getMessage();
} catch (Luminova\Exceptions\RuntimeException $e) {
    // Handle specific errors here.
    echo $e->getMessage();
} catch (\Throwable $e) {
    // Handle specific errors here.
    echo $e->getMessage();
}

Catch and Logging Exceptions

In cases where you want to log the exception rather than handle it directly, you can do so as follows:

try {
    $pdo = loginAccount($username, $password);
} catch (\Throwable $e) {
    // Log if it's not a core PHP exception type.
    // To ensure that log method exists
    if ($e instanceof Luminova\Exceptions\AppException) {
        // Log AppException details.
        $e->log('debug');
        return;
    } 

    // Log PHP exceptions using a logger.
    Logger::debug($e->getMessage());
}

Catch and Handle Exceptions

Based on Environment, you can manage exceptions differently based on your environment, throwing exceptions during development and logging them in production:

use Luminova\Exceptions\AppException;
use Exception;

try {
    $pdo = loginAccount($username, $password);
} catch (\Throwable $e) {
    if ($e instanceof Luminova\Exceptions\AppException) {
        // Handle AppException accordingly.
        $e->handle(); 
        return;
    }

    // Handle generic PHP exceptions gracefully.
    if(PRODUCTION){
        Logger::error($e->getMessage());
        return;
    }

    throw $e;
}

Class Definition


Methods

constructor

Create a new exception instance.

When an exception object is created with a message, an optional code, and a previous exception, it can be thrown using the throw keyword or pass the object to methods or return types.

public __construct(string $message, string|int $code = 0, ?\Throwable $previous = null): mixed

Parameters:

ParameterTypeDescription
$messagestringThe error message for the exception.
$codestring|intThe exception code as a string or integer (default: 0).
$previous\Throwable|nullThe previous exception object, if available (default: null).

Usages Example

Initialize and throws an exception:

use Luminova\Exceptions\AppException;
use Luminova\Exceptions\RuntimeException;

try{
    throw new RuntimeException('An error occurred');
}catch(AppException $e){
    // handle exception
}

isCode

Checks if the current exception's code matches a given code or any in an array.

Compares the provided code(s) against the exception's string code (if available) or its numeric code as a fallback.

public isCode(string|array<int,string|int>|int $code): bool

Parameters:

ParameterTypeDescription
$codestring|array|intThe code or list of codes to compare against.

Return Value:

bool - Returns true if a match is found, otherwise false.


setCode

Sets the exception code.

public setCode(string|int $code): self

Parameters:

ParameterTypeDescription
$codestring|intThe string or integer representation of the exception code.

Return Value:

self - Returns the current instance for method chaining.


setFile

Sets the file where the error occurred.

public setFile(string $file): self

Parameters:

ParameterTypeDescription
$filestringThe file where the error occurred.

Return Value:

self - Returns the current instance for method chaining.


setLine

Sets the line number where the error occurred.

public setLine(int $line): self

Parameters:

ParameterTypeDescription
$lineintThe line number of the error.

Return Value:

self - Returns the current instance for method chaining.


getDescription

Get a formatted message.

This method returns a filtered exception message, ensuring messages doesn't contain any sensitive information like private server paths.

public getDescription(): string

Return Value:

string - Return the filtered exception message.

Example:

You can retrieve a filtered error message that omits file details:

use Luminova\Exceptions\ErrorException;

try {
    $pdo = loginAccount($username, $password);
} catch (ErrorException $e) {
    echo $e->getDescription(); // Get a user-friendly error message.
}

getName

Get an exception error name.

This method returns a humanized exception name based on the exception code.

public getName(): string

Return Value:

string - Return the name of the thrown exception.

Example:

To retrieve a user-friendly name for the exception, use the following method:

use Luminova\Exceptions\ErrorException;

try {
   $pdo = loginAccount($username, $password);
} catch (ErrorException $e) {
   echo $e->getName(); // Get a human-readable name for the error.
}

getErrorCode

Get a string or an integer error code for thrown exception.

Unlike getCode method, this method returns an integer or string error code of the exception. It first checks if a string error code is set ($strCode), if not, falls back to the numeric error code.

public getErrorCode(): string|int

Return Value:

string|int - Return the error code as either a string or an integer. Returns the string error code if set, otherwise returns the numeric error code.


getBacktrace

Retrieve the las debug tracer.

This attempt to get last debug backtrace from the exception or shared error context.

public getBacktrace(): array

Return Value:

array - Return the debug backtrace, or an empty array if not available.

This method checks for the exception backtrace, if not available it checks for the stored debug backtrace in the shared memory __ERROR_DEBUG_BACKTRACE__ if still unavailable, it returns an empty array.

Example:

You can obtain backtrace information from an exception:

use Luminova\Exceptions\ErrorException;

try {
   $pdo = loginAccount($username, $password);
} catch (ErrorException $e) {
   print_r($e->getBacktrace()); // Print backtrace for debugging.
}

toString

Returns a formatted error message with code, file, and line details.

Format:The message returns in this format: Exception: (code) message in file/path/foo.php on line N.

public toString(): string

Return Value:

string - Return the formatted error message with code, file, and line number.

Example:

use Luminova\Exceptions\RuntimeException;

try{
   throw new RuntimeException('An error occurred');
}catch(RuntimeException $e){
   echo $e->toString();
   // Output: Exception: (0) An error occurred in /path/to/file.php on line 12
}

log

Logs the exception message to the configured logger.

Uses App\Config\Logger. If asynchronous logging is enabled, logs use Fiber for async processing. In production, if logger.mail.logs or logger.remote.logs is set, logs are sent via email or to a remote server.

Log Levels:

  • emergency - Log emergency error that need attention.
  • alert - Log alert message.
  • error - Log minor error.
  • warning - Log a warning message.

For more log level see Log Levels documentation.

public log(string $dispatch = 'exception'): void

Parameters:

ParameterTypeDescription
$dispatchstringA log level, email address, or remote URL to send the error to (default: exception).

Example:

This example demonstrates catching an exception and logging an exception message with a custom log level.

use Luminova\Exceptions\RuntimeException;

try{
    throw new RuntimeException('An error occurred');
}catch(RuntimeException $e){
    $e->log('debug');
}

handle

Handles exceptions safely depending on the application environment and error type.

This method ensures that exceptions are processed appropriately:

  • In CLI mode: either re-throws the exception (if enabled) or shows a CLI-friendly error detail.
  • In production: logs the error, shows a user-friendly page for fatal errors, and prevents leaks of sensitive information.
  • In development: re-throws the exception so it can be displayed directly.

The handler also prevents recursive exception handling and ensures consistent shutdown behavior.

public handle(): void

Throws:

  • Luminova\Interface\AppException<\T, Throwable> - Re-throws the exception in non-production environments or when explicitly configured for CLI.

Example:

This below example shows how you can catch an exception and handle it with handle method.

use Luminova\Exceptions\RuntimeException;

try{
    throw new RuntimeException('An error occurred');
}catch(RuntimeException $e){
    $e->handle();
}

throwException

Creates and handles an exception gracefully.

public static throwException(string $message, string|int $code = 0, ?\Throwable $previous = null): void

Parameters:

ParameterTypeDescription
$messagestringThe exception message.
$codestring|intThe exception code (default: 0).
$previous\Throwable|nullThe previous exception, if available (default: null).

Throws:

  • Luminova\Exceptions\AppException<\T> - Throws in development environment or if the exception code is fatal, otherwise log the information.

Example:

The following example demonstrates how to handle an exception gracefully in a production environment.For more error codes, refer to Exceptions and Error Handling.

use Luminova\Exceptions\Code;
use Luminova\Exceptions\AppException;
use Luminova\Exceptions\RuntimeException;

try {
    throw new RuntimeException('An error occurred');
} catch (\Throwable $e) {
    if($e instanceof AppException) {
        $e->handle();
        return;
    }

    // If not instance of AppException, create safe exception handler from the exception object.
    RuntimeException::throwException(
        $e->getMessage(), 
        Code::COMPILE_ERROR,
        $e
    );
}

throwAs

Rethrow or handle an exception as a specified exception class.

If the given Throwable is already an instance of Luminova\Exceptions\AppException, it will be handled directly. Otherwise, a new exception of the specified class (or the current class if not provided) will be created with the same message, code, and previous exception, then handled.

public static throwAs(\Throwable $e, ?string $abstract = null): void

Parameters:

ParameterTypeDescription
$e\ThrowableThe original exception object to be thrown or handled.
$abstractclass-string|nullThe new exception class to throw as (e.g., Luminova\Exceptions\RuntimeException). Defaults to the current class if null.

Throws:

  • \T<Throwable> - Throws the exception from the called class.

Example:

Throw Error exception as RuntimeException and handle it gracefully:

use Luminova\Exceptions\AppException;
use Luminova\Exceptions\RuntimeException;

try {
    throw new \Error('An error occurred');
} catch (\Throwable $e) {
    if($e instanceof RuntimeException) {
        $e->handle();
        return;
    }

    AppException::throwAs($e, RuntimeException::class);
}

Available Exception Classes

Luminova provides a robust set of predefined exception classes that extend the Luminova\Exceptions\AppException class. These exceptions cover a wide range of error scenarios, ensuring that your application can handle various issues gracefully.

The global namespace group for these classes is: Luminova\Exceptions\.

ClassDescription
AppExceptionThe base exception class for all Luminova-specific exceptions.
BadMethodCallExceptionThrown when a callback refers to an undefined method or an invalid context.
CacheExceptionRepresents errors related to caching operations.
ClassExceptionIndicates issues related to class handling, such as instantiation failures.
CookieExceptionThrown when there are problems with cookie operations.
DatabaseExceptionGeneral exception for database-related errors.
DatabaseLimitExceptionRaised when a query exceeds predefined database limits.
DateTimeExceptionHandles errors related to date and time operations.
EncryptionExceptionIndicates failures in encryption or decryption processes.
ErrorExceptionRepresents generic errors that don't fall under a specific category.
FileExceptionThrown when file-related operations fail, such as reading or writing files.
InvalidArgumentExceptionRaised when an argument provided to a method is invalid or out of range.
InvalidExceptionGeneral exception for invalid operations or inputs.
InvalidObjectExceptionIndicates that an object is invalid or not in the expected state.
JsonExceptionHandles errors related to JSON encoding or decoding.
LogicExceptionHandles errors related to implementation and logic issues.
MailerExceptionThrown when email sending operations fail.
NotFoundExceptionRaised when a required resource or entity cannot be found.
RouterExceptionRepresents issues related to routing operations within the application.
RuntimeExceptionGeneral exception for runtime errors that occur during application execution.
SecurityExceptionIndicates security-related issues, such as unauthorized access attempts.
StorageExceptionThrown when there are issues with storage operations, such as saving or retrieving data.
ValidationExceptionRaised when data fails to pass validation checks.
ViewNotFoundExceptionThrown when a requested view file cannot be located.

Luminova also provides custom exception classes specifically for handling network-related errors. These exceptions may be thrown when using the Luminova\Http\Network class.

The global namespace group for Http exception classes is: Luminova\Exceptions\Http\.

ClassDescription
ClientExceptionRepresents client-side errors during HTTP requests, such as 4xx status codes.
ConnectExceptionThrown when a connection to a remote server fails.
RequestExceptionHandles errors that occur during the creation or processing of HTTP requests.
ServerExceptionRepresents server-side errors encountered during HTTP requests, such as 5xx status codes.