0

I am developing an PHP API REST using Value Objects. I have some value objects as like: ID, Date, Name, etc. When they fail in their construction due to a invalid format or something it throws a InvalidArgumentException.

How can I "collect" all the Exceptions and when the script stops send them in an "error" array in the json response?

The problem is that i think that make hundred of try catch for each value object is not the best way, and I can not find the way to catch multiple exceptions in a try block.

Value Object that may throw an InvalidArgumentException

$authorID = new ID('dd'); // Must be an integer greather than 0 or null

Also I want to pass this ValueObject in the constructor of a Entity

 new Insertable($authorID);

If i have multiple ValueObjects that may throw Exceptions, how can I catch them all and make a response with these exceptions as "error" array?

Thanks!

2 Answers2

0

This is not especially elegant, but a possible solution. Just create a global $errors array and collect all messages.

$errors = [];

try {
    $authorID = new ID('dd');
} catch(Exception $e) {
    $errors[] = $e->getMessage();
}

// and collect some more

try {
    $authorID = new ID('ff');
} catch(Exception $e) {
    $errors[] = $e->getMessage();
}

At the end output them all

echo json_encode(['errors' => $errors], JSON_PRETTY_PRINT);

will give something like

{
    "errors": [
        "Author ID needs to be numeric",
        "Author ID needs to be numeric"
    ]
}
Markus Zeller
  • 8,516
  • 2
  • 29
  • 35
  • Sorry, my head is burned and I forgot to add this part to the example. I have make this same solution but I want to change it because it is not elegant and it's for a technical test... I am sorry! – Lautaro Aguirre Sep 20 '20 at 18:07
  • To make it really elegant, you should stop execution as soon as possible after the first exception occurs. Why should you catch many exceptions, if the first one is always the most relevant? You also should post this question on `code review stack exchange`, I think there it would fit there best, because this one is not really is a coding 'problem'. – Markus Zeller Sep 20 '20 at 18:15
  • I am learning value objects. All people says that in case if the value of that object is invalid, it must throw an exception. If multiple VO throws exceptions, how can i catch them all so I do not show only 1 exception to the user in each retry?. I can't understand... I'll look in stack exchange – Lautaro Aguirre Sep 20 '20 at 18:24
  • The use of exceptions is to exit a program at a fatal situation. So if one occurred, the program should probably show it and exit instantly after freeing all resources. When you handle many of them you get a (over)complicated flow. – Markus Zeller Sep 20 '20 at 19:37
  • Also think, that when an exception occured and you "ignore it", you certainly will create more following exceptions due to working with invalid values. Why should you want to collect them? Example: Database connection failed, why continue, when queries are mandatory? Any successive query WILL fail and throw more exceptions. Only the first one (can't connect) is the really relevant. So quit after first one. – Markus Zeller Sep 20 '20 at 19:41
-1

We only need to use a single try-catch block as it can handle multiple error(s)/exception(s) in a single go. Example:

try {
    $x = 5;

    //Statement 1
    throw_if(x===5, new Exception('Some Message'));

    //Statement 2
    throw_if(x===2, new Exception('Some Message'));

    //go ahead with your logic
} catch(Exception $e) {
    $message = $e->getMessage();
    //send error response here
} 

If you want to collect all the error(s)/exception(s) and return them all in error response then do so. Example:

$errors = [];
try {
    $x = 5;

    //Statement 1
    if($x===5) {
        $errors['stmt1'] = 'Some Message';
    }

    //Statement 2
    if($x===2) {
        $errors['stmt2'] = 'Some Message';
    }

    if(count($errors) > 0) {
        //return the $errors here as it contains all error(S)/exception(s)
    }

    //go ahead with your logic
} catch(Exception $e) {
    $message = $e->getMessage();
    //Any unknown error/exception will be catches here
} 
Ankit Singh
  • 922
  • 9
  • 16