The Throwable Hierarchy

Everything you can throw implements Throwable, and your classes must extend Error or Exception to do so. Error means the engine found what is almost always a bug: a wrong type, a division by zero. Exception means a failure to expect, such as bad input or a timeout.

The Throwable hierarchy: the engine's Error branch and the Exception branch you extend
The Throwable hierarchy: the engine's Error branch and the Exception branch you extend

Reflection prints the real tree. The script keeps core and SPL classes; extensions add about thirty more, such as JsonException and PDOException.

Listing the core Throwable class tree with ReflectionPHP
<?php
$tree = [];
foreach (get_declared_classes() as $name) {
    $c = new ReflectionClass($name);
    if ($c->implementsInterface(Throwable::class)
        && in_array($c->getExtensionName(), ['Core', 'SPL'])) {
        $tree[$c->getParentClass()?->name ?? 'Throwable'][] = $name;
    }
}
foreach ($tree as $parent => $kids) echo "$parent <- ", implode(', ', $kids), "\n";
Output
Throwable <- Exception, Error
Exception <- ErrorException, RequestParseBodyException, ClosedGeneratorException,
  LogicException, RuntimeException
Error <- CompileError, TypeError, ValueError, ArithmeticError, UnhandledMatchError, FiberError
CompileError <- ParseError
TypeError <- ArgumentCountError
ArithmeticError <- DivisionByZeroError
LogicException <- BadFunctionCallException, DomainException, InvalidArgumentException,
  LengthException, OutOfRangeException
BadFunctionCallException <- BadMethodCallException
RuntimeException <- OutOfBoundsException, OverflowException, RangeException,
  UnderflowException, UnexpectedValueException

Every Throwable offers getMessage(), getCode(), getFile(), getLine(), getTrace() and getPrevious(). catch (Exception $e) does not catch a TypeError, so a top-level safety net catches Throwable, and catch (RuntimeException $e) also receives a PDOException.