Answer the question
In order to leave comments, you need to log in
Is it possible to throw an exception in predicates?
Good day.
The question concerns the cleanliness of the code and the harmony of the architecture. It's no secret that predicates are functions that must return a boolean value in response to some question (is directory exists?). Since I started to get into a lot of exceptions a year ago (because they rule), I now rarely return false or null in cases where false or null should cause the program to terminate. I keep returning them when the situation is valid, but when it's an error, I always throw an exception.
Actually, the essence of the question is that in some cases it is convenient to put the throw of an exception into a predicate. Thus, in some cases it will only return true or throw an exception. It's better not to do that, right? And how to do in such cases, if you want to encapsulate the code that throws the exception into a function? Make an additional wrapper function over the predicate?
<?php
class CheckForNewPhoto
{
public function handle(Repositories\MosaicRepository $MosaicRepository)
{
if($this->isDirectoryNameCorrect()) {
// ранее исключение выбрасывалось тут, я считаю, это некрасиво
// do stuff
}
throw new Exceptions\UnexpectedError(
'Something wrong here'
);
}
/**
* Вот это - предикат. Я сделал так, чтобы избавить entry point,
* функцию handle, от ада выбросов исключений, когда проверяется много
* условий и выкидывается много исключений в одном методе.
* Когда один метод > одна проверка > строго связанные с ней исключения,
* это красиво.
*/
private function isDirectoryNameCorrect()
{
if(!config('mosaic.directory', null)) {
throw new Exceptions\InvalidSettingsException(
'Directory for mosaic photos is not setup properly'
);
}
return true;
}
}
Answer the question
In order to leave comments, you need to log in
He who holds a hammer in his hand sees only nails.
The example just perfectly illustrates the fact that exceptions are not needed here for nothing.
For the isDirectoryNameCorrect question, we only want to get "yes" or "no".
At the same time, we are not at all worried about why "no" - either the character set in the name is invalid, or the disk has fallen, or there are not enough rights - we are not interested.
The problem is no longer when to throw an exception, but when to catch it! In your particular example, you will need to catch the exception, complete the file operation, and continue execution.
Do you really want to drop the application if the user has selected the wrong directory in the settings? For example, a flash drive was selected and then it was removed, your program will try to open the directory and fall.
Exceptions is a good name. Exact. Lucky.
They should be used in unforeseen situations.
The situation you describe is typical.
It is correct to return true or false here.
Exceptions is a bad name. Confusing. Unsuccessful.
In fact, there is an alternative flow of control behind this: there is the usual flow of program execution, and there is a way to teleport from the point where the exception is raised to the point where it is handled. And this can be very convenient: for example, you are looking for something by recursive traversal of the graph, found it - threw an exception, and picked it up with a handler outside the traversal function. This is very convenient - you don't need to return true/false when exiting the function, but check it at the call point, it turns out simply and elegantly.
To treat a situation as exceptional or not is a matter of design. You can either do a predicate, but then this thing should return true or false and throw exceptions in other situations - for example, when there is not enough memory.
Or make a check and throw an exception, but then there is no need to return true - it will no longer be a predicate.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question