Skip to content

PHP Tutorial Error Handling

The throw Statement

Lesson 191 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

throw raises an exception. You use it when your code finds a situation it cannot continue from.

index.php
PHP
<?php
function setAge(int $age): int
{
    if ($age < 0 || $age > 150) {
        throw new InvalidArgumentException("Age must be between 0 and 150, got $age.");
    }

    return $age;
}

try {
    setAge(-5);
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
}
Output
OUTPUT
Age must be between 0 and 150, got -5.

What a good message looks like

  • Says what is wrong and, if possible, what was received.
  • Is written for the programmer, not the visitor.
  • Contains no secrets (passwords, tokens).
index.php
PHP
throw new InvalidArgumentException("Email is required");                 // short, fine
throw new RuntimeException("Could not open $file for writing");          // includes the cause
throw new Exception("Error");                                            // too vague

throw is an expression (PHP 8.0+)

Since PHP 8, throw can be used inside an expression, which makes short checks possible.

index.php
PHP
<?php
function findUser(array $users, int $id): string
{
    return $users[$id] ?? throw new OutOfBoundsException("No user with id $id");
}

$users = [1 => "Ana", 2 => "Ben"];

echo findUser($users, 2) . "\n";

try {
    findUser($users, 9);
} catch (OutOfBoundsException $e) {
    echo $e->getMessage();
}
Output
OUTPUT
Ben
No user with id 9

It also works in arrow functions and ternaries.

index.php
PHP
<?php
$check = fn($x) => $x > 0 ? $x : throw new RangeException("Must be positive");

echo $check(5);
Output
OUTPUT
5

Rethrowing

Inside a catch, you can throw the same exception again after you have done something with it (for example, logged it).

index.php
PHP
<?php
try {
    try {
        throw new RuntimeException("inner problem");
    } catch (RuntimeException $e) {
        echo "Logging: " . $e->getMessage() . "\n";
        throw $e;   // pass it on
    }
} catch (RuntimeException $e) {
    echo "Handled at the top: " . $e->getMessage();
}
Output
OUTPUT
Logging: inner problem
Handled at the top: inner problem

Throw early, catch late

Check your inputs at the top of a function and throw straight away. Handle the exception at a higher level where you know how to respond (show a message, return an HTTP error).

Exceptions are for exceptional cases

Do not use exceptions for normal control flow, such as “the loop is finished”. Use them for things that should not happen in a correct run: invalid input, missing resources, broken assumptions.

throw needs a Throwable

You can only throw objects that implement Throwable. throw "error"; is itself an error.

Exercise: validate an email

Write requireEmail(string $email): string that throws an InvalidArgumentException when the address is not valid. Test it with a valid and an invalid address.

Show a possible solution
index.php
PHP
<?php
function requireEmail(string $email): string
{
    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        throw new InvalidArgumentException("Invalid email: $email");
    }

    return $email;
}

echo requireEmail("ana@example.com") . "\n";

try {
    requireEmail("nope");
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
}
Output
OUTPUT
ana@example.com
Invalid email: nope