I have recently updated a colleagues code by rather taking advantage of the map function offered by the Collection object within the Support namespace.
He's just asked me if he can use a try-catch block within the map function itself and I unreservedly said yes.
I had my reservations though I should admit and thought let me do a quick test for this. Below is the test case that I have put together with a sample class that uses the collection object within a test method. Can someone shed some light to me around this whether it is possible or not In my opinion a callable should be able to adapt to any kind of code written within it maybe my understanding of callable is limited else I do not understand how the collection API works:
use PHPUnit\Framework\TestCase;
class TeamMembersTest extends TestCase
{
/**
* @test
*/
public function it_can_execute_try_catch_within_laravels_collection_map_method_call()
{
$this->expectExceptionMessage("This member is no longer part of this team.");
try{
(new TeamMembers())->checkMate('Abigail');
}catch(Exception $exc){
throw $exc;
}
}
}
class TeamMembers
{
public function checkMate($member)
{
$teamMembers = array('Luyanda', 'Matthew', 'Scott', 'Belinda', 'Roxanne');
(new \Illuminate\Support\Collection($teamMembers))->map(function($teamMember) use($member){
try{
if($member == 'Abigail'){
throw new Exception(
"This member is no longer part of this team."
);
}
}catch(Exception $exc){
}
});
}
}
Below I have the results of the test case which is wrtten in PHPUnit:
PHPUnit 6.5.7 by Sebastian Bergmann and contributors.
Runtime: PHP 7.0.10
Configuration: path/to/phphunit/config.xmll
F 1 / 1 (100%)
Time: 93 ms, Memory: 8.00MB
There was 1 failure:
1) TeamMembersTest::it_can_execute_try_catch_within_laravels_collection_map_method_call
Failed asserting that exception with message "This member is no longer part of this team." is thrown
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
Maybe it is how I have wired my tests altogether I really am not sure. The callback attached to the map function does get executed though except for the try-catch block.
Thanks in advance
Hi Luyanda,
try-catch blocks will work fine inside the map callback generally speaking.
However looking at your code example there are a few things to comment on here ...
Your test is expecting the exception to be thrown, however because you are actually catching the exception within the try-catch block, that test will always fail.
If you comment out the try-catch block, the test will pass as the exception is thrown, the fact that the test fails with the try-catch block further confirms that the try-catch is working, however as mentioned, you're catching your own exception here.
In this sort of scenario you would more likely catch a general exception in the try and then throw a more meaningful custom exception to your application in the catch block.
Finally, without knowing more about the specific use case, it's hard to say what might be a better solution.
Regards,
Robert
Indeed.
Your suggestion worked.
I understand what you are saying but I was trying to emulate how the try-catch block was being used within the map function. I think in that same token I also got lost :-)
Tks,
Lu
Most helpful comment
Hi Luyanda,
try-catch blocks will work fine inside the map callback generally speaking.
However looking at your code example there are a few things to comment on here ...
Your test is expecting the exception to be thrown, however because you are actually catching the exception within the try-catch block, that test will always fail.
If you comment out the try-catch block, the test will pass as the exception is thrown, the fact that the test fails with the try-catch block further confirms that the try-catch is working, however as mentioned, you're catching your own exception here.
In this sort of scenario you would more likely catch a general exception in the try and then throw a more meaningful custom exception to your application in the catch block.
Finally, without knowing more about the specific use case, it's hard to say what might be a better solution.
Regards,
Robert