Framework: Collection `map` function cannot trigger exception with a try-catch block

Created on 12 Jun 2018  路  2Comments  路  Source: laravel/framework

  • Laravel Version: 5.6.*
  • PHP Version: 7.2
  • Database Driver & Version: MySQL

Description:

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:

Steps To Reproduce:

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

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

All 2 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JamborJan picture JamborJan  路  3Comments

iivanov2 picture iivanov2  路  3Comments

digirew picture digirew  路  3Comments

ghost picture ghost  路  3Comments

Fuzzyma picture Fuzzyma  路  3Comments