← Back to PHP Course | Chapter 13: Error Handling | Lesson 3 of 5

PHP Custom Exceptions

Creating a Custom Exception Class

Extending PHP's built-in Exception class lets you define your own exception types (like InvalidUserException), which makes it possible to catch and handle specific failure categories differently instead of treating every error the same way.

Example: Creating a Custom Exception Class

php
<?php
class InvalidUserException extends Exception {}

try {
    throw new InvalidUserException("User not found");
} catch (InvalidUserException $e) {
    echo $e->getMessage();
}
?>

Custom Error Formatting

Because a custom exception class is just a class, you can add your own methods and properties to it -- for example a method that formats a user-friendly message from internal error details.

Example: Custom Error Formatting

php
<?php
class AppException extends Exception {
    function friendlyMessage() {
        return "Oops: " . $this->getMessage();
    }
}
try {
    throw new AppException("Database unreachable");
} catch (AppException $e) {
    echo $e->friendlyMessage();
}
?>

Throwing Custom Exceptions

Throwing a custom exception instead of a generic one turns validation failures into self-documenting code: catching a StockUnavailableException communicates intent far better than a bare Exception ever could.

Example: Throwing Custom Exceptions

php
<?php
class StockUnavailableException extends Exception {}

function order($qty, $stock) {
    if ($qty > $stock) {
        throw new StockUnavailableException("Not enough stock");
    }
}
try {
    order(5, 2);
} catch (StockUnavailableException $e) {
    echo $e->getMessage();
}
?>

Multiple Custom Catches

Catching several custom exception types separately lets each one trigger its own recovery path -- retrying a network call differs completely from asking a user to fix invalid input.

Example: Multiple Custom Catches

php
<?php
class NetworkException extends Exception {}
class ValidationException extends Exception {}

function process($type) {
    if ($type === "network") throw new NetworkException("Connection lost");
    throw new ValidationException("Bad input");
}
try {
    process("network");
} catch (NetworkException $e) {
    echo "Retrying: " . $e->getMessage();
} catch (ValidationException $e) {
    echo "Fix input: " . $e->getMessage();
}
?>

Rethrowing Custom Exceptions

Sometimes you want to log an exception locally and still let a caller further up the stack handle it too; re-throwing it with throw $e inside a catch block does exactly that without losing the original error.

Example: Rethrowing Custom Exceptions

php
<?php
class AppException extends Exception {}

function risky() {
    throw new AppException("Something broke");
}
try {
    try {
        risky();
    } catch (AppException $e) {
        error_log($e->getMessage());
        throw $e;
    }
} catch (AppException $e) {
    echo "Handled higher up: " . $e->getMessage();
}
?>
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.