I agree with all that you wrote but I have one question - wouldn't it be "better" to write this "login" function as below:
public function login($email, $user)
{
if(!$this->isEmailValid()) {
throw LoginException::emailNotValid($email);
} ...
or:
public function login($email, $user)
{
try {
$this->isEmailValid(); // throws EmailException
$this->registerUser(); // throws RegistrationEx
} catch (EmailException $e) {
...
} catch (RegistrationException $e) {
....
}
...
I'm not sure if these "return" statements placed not at the end of the function should not also be considered as the code smell :)