M
M
microf2019-12-21 08:32:50
Exceptions
microf, 2019-12-21 08:32:50

What is the right way to throw an exception?

We have an Address class with a constructor

public function __construct(string $country,string $city, string $street, string $house, string $building = '') {}

I want to validate all parts of the address (country, city, street, house, building). It all succeeds
private function isCountryValid($param) {
        if (empty($param) || !preg_match("/^[а-яё0-9- ]+$/iu", $param)) {
            throw new AddressWithoutCountryException($param);
        }
    }

and the test can be written normally
public function testAddressCreatedWithoutCountry() {
        $this->expectException(AddressWithoutCountryException::class);
        CreateCompanyBuilder::instance()->withAddress(new Address('', 'Москва', 'Солнечная', '15',''))->build();
    }

But what if I want to make a test with no parameters at all
public function testCreateCompanyWithoutAddress() {
        $this->expectException(CompanycWithoutAddressException::class);
        CreateCompanyBuilder::instance()->withAddress(new Address())->build();
    }

In this case, it is logical that
Failed asserting that exception of type "ArgumentCountError" matches expected exception ... at least 4 expected

Question number one is how to override ArgumentCountError, (and where) to throw an exception like
class CompanyWithoutAddressException extends ArgumentCountError {
    
    public function __construct()
    {
        parent::__construct('У организации должен быть заполнен адрес');
    }

Now `ArgumentCountError` exception is still thrown even if you do this
public function __construct(string $country,string $city, string $street, string $house, string $building = '0') {
        if (!$country && !$city && !$street && !$house) {
            throw new CompanyWithoutAddressException();
        }

And the second question is how best to pass parameters to the constructor
string $country,string $city, string $street, string $house, string $building = ''
with optional parameter $building (building). It may or may not be. You can remove it from the constructor and pass it as a setter, but I would like to put the entire dto directly into the constructor.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
Boris Korobkov, 2019-12-21
@BorisKorobkov

Make all parameters optional (or pass them as a single array or via setters), check the passed and throw the necessary exceptions.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question