Skip to content

Introduce subtypes of InvalidArgumentException #809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Exception/CurrencyMismatchException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Money\Exception;

final class CurrencyMismatchException extends InvalidArgumentException
{
}
9 changes: 9 additions & 0 deletions src/Exception/DivisionByZeroException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Money\Exception;

final class DivisionByZeroException extends InvalidArgumentException
{
}
19 changes: 14 additions & 5 deletions src/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,26 @@
use InvalidArgumentException as CoreInvalidArgumentException;
use Money\Exception;

final class InvalidArgumentException extends CoreInvalidArgumentException implements Exception
/**
* @internal
*/
class InvalidArgumentException extends CoreInvalidArgumentException implements Exception
{
/** @phpstan-pure */
public static function divisionByZero(): self
public static function divisionByZero(): DivisionByZeroException
{
return new self('Cannot compute division with a zero divisor');
return new DivisionByZeroException('Cannot compute division with a zero divisor');
}

/** @phpstan-pure */
public static function moduloByZero(): self
public static function moduloByZero(): ModuloByZeroException
{
return new self('Cannot compute modulo with a zero divisor');
return new ModuloByZeroException('Cannot compute modulo with a zero divisor');
}

/** @phpstan-pure */
public static function currencyMismatch(): CurrencyMismatchException
{
return new CurrencyMismatchException('Currencies must be identical');
}
}
9 changes: 9 additions & 0 deletions src/Exception/ModuloByZeroException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Money\Exception;

final class ModuloByZeroException extends InvalidArgumentException
{
}
12 changes: 6 additions & 6 deletions src/Money.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Money;

use InvalidArgumentException;
use JsonSerializable;
use Money\Calculator\BcMathCalculator;
use Money\Exception\InvalidArgumentException;

use function array_fill;
use function array_keys;
Expand Down Expand Up @@ -135,7 +135,7 @@ public function compare(Money $other): int
{
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $other->currency) {
throw new InvalidArgumentException('Currencies must be identical');
throw InvalidArgumentException::currencyMismatch();
}

// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
Expand Down Expand Up @@ -209,7 +209,7 @@ public function add(Money ...$addends): Money
foreach ($addends as $addend) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $addend->currency) {
throw new InvalidArgumentException('Currencies must be identical');
throw InvalidArgumentException::currencyMismatch();
}

// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
Expand All @@ -232,7 +232,7 @@ public function subtract(Money ...$subtrahends): Money
foreach ($subtrahends as $subtrahend) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $subtrahend->currency) {
throw new InvalidArgumentException('Currencies must be identical');
throw InvalidArgumentException::currencyMismatch();
}

// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
Expand Down Expand Up @@ -291,7 +291,7 @@ public function mod(Money|int|string $divisor): Money
if ($divisor instanceof self) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $divisor->currency) {
throw new InvalidArgumentException('Currencies must be identical');
throw InvalidArgumentException::currencyMismatch();
}

$divisor = $divisor->amount;
Expand Down Expand Up @@ -385,7 +385,7 @@ public function ratioOf(Money $money): string

// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $money->currency) {
throw new InvalidArgumentException('Currencies must be identical');
throw InvalidArgumentException::currencyMismatch();
}

return self::$calculator::divide($this->amount, $money->amount);
Expand Down
5 changes: 3 additions & 2 deletions tests/MoneyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use InvalidArgumentException;
use Money\Currency;
use Money\Exception\CurrencyMismatchException;
use Money\Money;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -294,7 +295,7 @@ public function itThrowsWhenCalculatingModulusOfDifferentCurrencies(): void
$money = new Money(self::AMOUNT, new Currency(self::CURRENCY));
$rightMoney = new Money(self::OTHER_AMOUNT, new Currency(self::OTHER_CURRENCY));

$this->expectException(InvalidArgumentException::class);
$this->expectException(CurrencyMismatchException::class);

$money->mod($rightMoney);
}
Expand Down Expand Up @@ -442,7 +443,7 @@ public function itThrowsWhenComparingDifferentCurrencies(): void
{
$money = new Money('5', new Currency(self::CURRENCY));

$this->expectException(InvalidArgumentException::class);
$this->expectException(CurrencyMismatchException::class);

$money->compare(new Money('5', new Currency('SOME')));
}
Expand Down