How can I use a string instead of an integer as the code of a custom exception in PHP?

Viewed 92

I've been searching for a way to use a string instead of an integer for the code of a custom exception, but much to my surprise this seems impossible to do!

I'd like to be able to throw such an exception:

throw new CustomException( "user_not_found", "User not found" );

so then I can test it as follows with PHPUnit:

$this->expectExceptionCode( "user_not_found" ); 
$User = new User(100); // 100 is a valid id for a non-existing user 
$User->delete_user(); // This method throws the above CustomException

What I've been doing so far is passing a custom context array to the exception:

throw new CustomException( "User not found", [ "debug" => "user_not_found" ] );

and then my test looks like this:

try {
    $User = new User(100);
    $User->delete_user();
} catch( \Throwable $e ) {
    $this->assertEquals( "user_not_found", $e->getContext()["debug"] );
}

But I would really prefer the first solution because it looks cleaner to me.

1 Answers

First, create base exception, like:

class MyBaseException extends \Exception {
    public function __constructor(string $key, string $message) {
        parent::__construct($message, ['debug' => $key]);
    }
}

Then, implement other exceptions, like:

class UserNotFoundException extends MyBaseException {
    public function __constructor() {
        parent::__constructor('user_not_found', 'User not found');
    }
}

Finally, write tests for class (not key and/or code), like:

$this->expectException(UserNotFoundException::class);

// Your throwing code 

$User = new User(100);
$User->delete_user();

See also: How to assert that an exception was thrown?

Related