A constructor that validated three things and threw one exception

A value object rejecting an invalid input with a message that named the type rather than the problem.

// before
if ($cents < 0 || $currency === '' || ! $this->known($currency)) {
    throw new InvalidArgumentException('invalid money');
}

// after
if ($cents < 0) {
    throw InvalidMoney::negativeAmount($cents);
}

if (! $this->known($currency)) {
    throw InvalidMoney::unknownCurrency($currency);
}

One check per condition and a named constructor per failure costs six lines and turns a support conversation into a log line. The message that says “invalid money” appears in a log with no context about which of three things was wrong, and the person reading it is you, in a year, with the input no longer available.