debugphpMinor
Throw an exception which contains a nested set of previous exceptions
Viewed 0 times
exceptionspreviousexceptionwhichnestedcontainsthrowset
Problem
I have a set of domain objects which try to find a solution to a problem.
The top level object has an algorithm which splits up the problem and delegates it to lower level objects, which in turn do the same.
I want the top level algorithm to throw an exception if it did not find any solutions, giving a breakdown of possible causes.
My question is, how should(n't) this be implemented?
The way I was thinking of doing this:
The algorithms at all levels throw an exception if it fails to find a solution.
For a given level, call it the parent algorithm, it would accumulate exceptions thrown by its children, and if all attempts by its children throw an exception, the parent will itself throw an exception which contains its childrens' exceptions.
My implementation is as follows:
I'm using it like this:
And when
I'm worried that this is bad practice. I've read that exceptions should only be used in exceptional circumstances. So with that in mind, perhaps I shoul
The top level object has an algorithm which splits up the problem and delegates it to lower level objects, which in turn do the same.
I want the top level algorithm to throw an exception if it did not find any solutions, giving a breakdown of possible causes.
My question is, how should(n't) this be implemented?
The way I was thinking of doing this:
The algorithms at all levels throw an exception if it fails to find a solution.
For a given level, call it the parent algorithm, it would accumulate exceptions thrown by its children, and if all attempts by its children throw an exception, the parent will itself throw an exception which contains its childrens' exceptions.
My implementation is as follows:
class ExceptionWithCauses extends \Exception {
private $causes = array();
public function addCause(\Exception $ex){
$this->causes[] = $ex;
$this->message .= "\n".$ex->getMessage();
}
}I'm using it like this:
function findAnOption()
{
$noOptionsException = new ExceptionWithCauses("findAnOption(): No options found");
$possibilities = array(1, 2, 3, 4);
foreach ($possibilities as $possibility)
{
try {
useOption($possibility);
return $possibility;
} catch (Exception $e) {
$noOptionsException->addCause($e);
}
}
throw $noOptionsException;
}
function useOption($x)
{
if ($x < 5){
throw new ExceptionWithCauses("useOption(): $x is too small");
}
return $x;
}And when
findAnOption() is called, a exception is thrown with the following message:findAnOption(): No options found
useOption(): 1 is too small
useOption(): 2 is too small
useOption(): 3 is too small
useOption(): 4 is too smallI'm worried that this is bad practice. I've read that exceptions should only be used in exceptional circumstances. So with that in mind, perhaps I shoul
Solution
The other way you could do this, noting that you don't actually use the return value of
useOption, is to have it return an error message or false, along the lines of:function findAnOption()
{
$problems = array();
$possibilities = array(1, 2, 3, 4);
foreach ($possibilities as $possibility)
{
$problem = useOption($possibility);
if ($problem === false) return $possibility;
$problems[] = $problem;
}
throw new SomeExceptionType($problems);
}
function useOption($x)
{
if ($x
The exception approach can certainly be clearer, and I wouldn't discard it just because it's "using exceptions for control flow". Exceptions are always control flow: the question is whether they're the appropriate one for a given case.
However, I would make one change: I prefer the name AggregateException (stolen unashamedly from Microsoft's .Net API) to ExceptionWithCauses`.Context
StackExchange Code Review Q#107862, answer score: 4
Revisions (0)
No revisions yet.