Bug #55416 [Com]: array_map() throws PHP warning if the callback throws an exception

2012-02-12 Thread harvey dot robin at gmail dot com
Edit report at https://bugs.php.net/bug.php?id=55416&edit=1

 ID: 55416
 Comment by: harvey dot robin at gmail dot com
 Reported by:roan dot kattouw at gmail dot com
 Summary:array_map() throws PHP warning if the callback
 throws an exception
 Status: Open
 Type:   Bug
 Package:Arrays related
 Operating System:   Ubuntu Natty
 PHP Version:5.4.0alpha3
 Block user comment: N
 Private report: N

 New Comment:

I've just come across this too and I'm really surprised at this inconsistent 
behavior, for me the question isn't "what kind of situation needs throw a 
exception in map function" but "why would the map function behave differently 
to any other situation".  If you change array_map to array_walk in the original 
example then the exception propagates upward, as expected.

At the very least, I'd expect to see a note on the PHP manual page warning 
users that exceptions work differently for the callback parameter to array_walk.


Previous Comments:

[2011-08-16 16:20:17] mah at everybody dot org

http://www.mediawiki.org/wiki/Special:Code/MediaWiki/94433 has Roan's actual 
use case.


[2011-08-15 09:35:40] roan dot kattouw at gmail dot com

Basically what I'm doing is

implode("\n", array_map('readStyleFile', $files)

where $files is an array of file names, and readStyleFile() can throw an 
exception if something is wrong (in this case it's if the file doesn't exist, 
but other cases are imaginable). This exception then propagates up a few levels 
and is caught and handled. Throwing an exception from inside the map callback 
works just fine: it stops the callback, stops array_map(), propagates up to the 
caller of array_map(), then works its way up the call stack like any other 
exception. The only issue is that warning that won't go away.


[2011-08-15 08:54:02] larue...@php.net

I was wondering what kind of situation needs throw a exception in map function?

and why doing that? thanks


[2011-08-13 20:40:11] roan dot kattouw at gmail dot com

Something I forgot to mention in the original report:

Using @array_map(...) suppresses the warning. However, it also suppresses any 
other notices or warnings that might happen in the callback. That's why I put 
the $foo = $bar['baz']; bit in barf(): if you use @array_map, the "Undefined 
variable" notice, which is legitimate, goes away as well.

More generally, @ is kind of a blunt instrument that often suppresses more than 
you expect it to, masking mistakes.


[2011-08-13 20:32:50] roan dot kattouw at gmail dot com

The attached patch fixes this by not throwing the warning if EG(exception) is 
not NULL. IMO the warning should be removed completely (because it's 
superfluous, and I don't see offhand how it can be triggered other than by an 
exception, but I don't know PHP core at all), but it's easy to tweak my patch 
into doing that instead; this patch is just the minimal solution.




The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

https://bugs.php.net/bug.php?id=55416


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=55416&edit=1


Bug #55416 [Com]: array_map() throws PHP warning if the callback throws an exception

2011-08-16 Thread mah at everybody dot org
Edit report at https://bugs.php.net/bug.php?id=55416&edit=1

 ID: 55416
 Comment by: mah at everybody dot org
 Reported by:roan dot kattouw at gmail dot com
 Summary:array_map() throws PHP warning if the callback
 throws an exception
 Status: Open
 Type:   Bug
 Package:Arrays related
 Operating System:   Ubuntu Natty
 PHP Version:5.4.0alpha3
 Block user comment: N
 Private report: N

 New Comment:

http://www.mediawiki.org/wiki/Special:Code/MediaWiki/94433 has Roan's actual 
use case.


Previous Comments:

[2011-08-15 09:35:40] roan dot kattouw at gmail dot com

Basically what I'm doing is

implode("\n", array_map('readStyleFile', $files)

where $files is an array of file names, and readStyleFile() can throw an 
exception if something is wrong (in this case it's if the file doesn't exist, 
but other cases are imaginable). This exception then propagates up a few levels 
and is caught and handled. Throwing an exception from inside the map callback 
works just fine: it stops the callback, stops array_map(), propagates up to the 
caller of array_map(), then works its way up the call stack like any other 
exception. The only issue is that warning that won't go away.


[2011-08-15 08:54:02] larue...@php.net

I was wondering what kind of situation needs throw a exception in map function?

and why doing that? thanks


[2011-08-13 20:40:11] roan dot kattouw at gmail dot com

Something I forgot to mention in the original report:

Using @array_map(...) suppresses the warning. However, it also suppresses any 
other notices or warnings that might happen in the callback. That's why I put 
the $foo = $bar['baz']; bit in barf(): if you use @array_map, the "Undefined 
variable" notice, which is legitimate, goes away as well.

More generally, @ is kind of a blunt instrument that often suppresses more than 
you expect it to, masking mistakes.


[2011-08-13 20:32:50] roan dot kattouw at gmail dot com

The attached patch fixes this by not throwing the warning if EG(exception) is 
not NULL. IMO the warning should be removed completely (because it's 
superfluous, and I don't see offhand how it can be triggered other than by an 
exception, but I don't know PHP core at all), but it's easy to tweak my patch 
into doing that instead; this patch is just the minimal solution.


[2011-08-13 19:58:06] roan dot kattouw at gmail dot com

Description:

If you map a function on an array using array_map(), and that function (the 
callback) then throws an exception, you get a PHP Warning saying "An error 
occurred while invoking the map callback". I guess this is sort of reasonable 
if an actual error occurred (even though that error would presumably have 
reported itself already, so it's superfluous), but an exception isn't an actual 
error unless the code that catches the exception decides it is.

This is annoying me because I'm squashing PHP warnings and notices in my code, 
but I can't get rid of this warning. I have a legitimate use case for throwing 
an exception from my map function, so I can either rewrite my code to not use 
an exception there (which would be extremely awkward) or write a foreach 
equivalent of the array_map() call (which would just be ridiculous; PHP 
provides array_map() for a reason: so you can write one-liners instead of 
repetitive foreach loops), or remove the IMHO misplaced warning in PHP.

I'll dig into the PHP source and see if I can come up with a patch.

Test script:
---
error_reporting(E_ALL);

function barf($i) {
$foo = $bar['baz'];
throw new Exception('barf');
}

$a = array(1, 2, 3);

try {
array_map('barf', $a);
} catch(Exception $e) {
echo $e;
}


Expected result:

Notice: Undefined variable: bar in /home/catrope/php-5.4.0alpha3/testcase.php 
on line 3

exception 'Exception' with message 'barf' in 
/home/catrope/php-5.4.0alpha3/testcase.php:3
Stack trace:
#0 [internal function]: barf(1)
#1 /home/catrope/php-5.4.0alpha3/testcase.php(6): array_map('barf', Array)


Actual result:
--
Notice: Undefined variable: bar in /home/catrope/php-5.4.0alpha3/testcase.php 
on line 3

Warning: array_map(): An error occurred while invoking the map callback in 
/home/catrope/php-5.4.0alpha3/testcase.php on line 6
exception 'Exception' with message 'barf' in 
/home/catrope/php-5.4.0alpha3/testcase.php:3
Stack trace:
#0 [internal function]: barf(1)
#1 /home/catrope/php-5.4.0alpha3/testcase.php(6): array_map('barf', Array)




Bug #55416 [Com]: array_map() throws PHP warning if the callback throws an exception

2011-08-13 Thread roan dot kattouw at gmail dot com
Edit report at https://bugs.php.net/bug.php?id=55416&edit=1

 ID: 55416
 Comment by: roan dot kattouw at gmail dot com
 Reported by:roan dot kattouw at gmail dot com
 Summary:array_map() throws PHP warning if the callback
 throws an exception
 Status: Open
 Type:   Bug
 Package:Arrays related
 Operating System:   Ubuntu Natty
 PHP Version:5.4.0alpha3
 Block user comment: N
 Private report: N

 New Comment:

The attached patch fixes this by not throwing the warning if EG(exception) is 
not NULL. IMO the warning should be removed completely (because it's 
superfluous, and I don't see offhand how it can be triggered other than by an 
exception, but I don't know PHP core at all), but it's easy to tweak my patch 
into doing that instead; this patch is just the minimal solution.


Previous Comments:

[2011-08-13 19:58:06] roan dot kattouw at gmail dot com

Description:

If you map a function on an array using array_map(), and that function (the 
callback) then throws an exception, you get a PHP Warning saying "An error 
occurred while invoking the map callback". I guess this is sort of reasonable 
if an actual error occurred (even though that error would presumably have 
reported itself already, so it's superfluous), but an exception isn't an actual 
error unless the code that catches the exception decides it is.

This is annoying me because I'm squashing PHP warnings and notices in my code, 
but I can't get rid of this warning. I have a legitimate use case for throwing 
an exception from my map function, so I can either rewrite my code to not use 
an exception there (which would be extremely awkward) or write a foreach 
equivalent of the array_map() call (which would just be ridiculous; PHP 
provides array_map() for a reason: so you can write one-liners instead of 
repetitive foreach loops), or remove the IMHO misplaced warning in PHP.

I'll dig into the PHP source and see if I can come up with a patch.

Test script:
---
error_reporting(E_ALL);

function barf($i) {
$foo = $bar['baz'];
throw new Exception('barf');
}

$a = array(1, 2, 3);

try {
array_map('barf', $a);
} catch(Exception $e) {
echo $e;
}


Expected result:

Notice: Undefined variable: bar in /home/catrope/php-5.4.0alpha3/testcase.php 
on line 3

exception 'Exception' with message 'barf' in 
/home/catrope/php-5.4.0alpha3/testcase.php:3
Stack trace:
#0 [internal function]: barf(1)
#1 /home/catrope/php-5.4.0alpha3/testcase.php(6): array_map('barf', Array)


Actual result:
--
Notice: Undefined variable: bar in /home/catrope/php-5.4.0alpha3/testcase.php 
on line 3

Warning: array_map(): An error occurred while invoking the map callback in 
/home/catrope/php-5.4.0alpha3/testcase.php on line 6
exception 'Exception' with message 'barf' in 
/home/catrope/php-5.4.0alpha3/testcase.php:3
Stack trace:
#0 [internal function]: barf(1)
#1 /home/catrope/php-5.4.0alpha3/testcase.php(6): array_map('barf', Array)







-- 
Edit this bug report at https://bugs.php.net/bug.php?id=55416&edit=1