Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.2.2

Bug #7692 readLine exits silently on error
Submitted: 2006-05-22 10:58 UTC
From: jason dot e dot stewart at gmail dot com Assigned: chagenbu
Status: Closed Package: Net_Socket (version 1.0.6)
PHP Version: 5.0.2 OS: Windows NT
Roadmaps: (Not assigned)    
Subscription  


 [2006-05-22 10:58 UTC] jason dot e dot stewart at gmail dot com (Jason Stewart)
Description: ------------ because readLine() calls @fgets(...) any error will cause the function to exit silently with no trace of what happened. This happens if max_execution_time is set low and there is a long process at the other end of the socket. This caused a really dificult to trace error. Because the error was a fatal error my custom error handler didn't even catch it... Why is @fgets() called and not just fgets()??

Comments

 [2006-05-22 11:01 UTC] jason dot e dot stewart at gmail dot com
this bug is linked to BUG# 7691
 [2006-05-22 18:05 UTC] chagenbu at php dot net (Chuck Hagenbuch)
Well, not everyone is using a custom error handler that would catch warnings. For some scripts, if a warning was generated (say a request times out), they might just want to get back a return false and redirect somewhere else - but oops, headers have already been sent. Since fgets() will only ever generate a warning, not a fatal error (by itself), we silence it.
 [2006-05-23 05:24 UTC] jason dot e dot stewart at gmail dot com
Maybe I was unclear. When the socket read exceeds the max_execution_time setting it causes a FATAL ERROR - this error is discarded because of @fgets(): PHP Fatal Error: maximum execution time of 30 secs exceeded in c:\Program Files\php5\PEAR\Net\Socket.php on line 448 My script exits completely because of this error - and nothing I do can trap it - so I am clueless what is happening. I was only able to get the above text by removing the '@' operator. Discarding warnings is one thing - but discarding errors is a righteous pain in the a**...
 [2006-05-26 18:18 UTC] chagenbu at php dot net (Chuck Hagenbuch)
Okay, I did misunderstand you. I have very mixed feelings about this. On the one hand, silencing a fatal error is never a good thing - completely with you on that. However there are probably a ton of applications and packages out there that expect Net_Socket not to generate warnings, thus potentially breaking header() calls, or generally mucking things up. I'm not sure what the answer is here. I wonder what would happen if we called ob_start() before the fgets/fread calls in question, assigned the data instead of returning it, then ob_end_clean(), finally return the result. That'd effectively silence warnings still; the question is if it'd silence the fatal error. Would you be willing to test this?
 [2006-05-27 17:02 UTC] jason dot e dot stewart at gmail dot com
yes, I still have my application set up on the test server. It would be easy to test. Send my a patch and I'll try it out.
 [2006-05-29 01:44 UTC] chagenbu at php dot net (Chuck Hagenbuch)
Here you are: Index: Socket.php =================================================================== RCS file: /repository/pear/Net_Socket/Socket.php,v retrieving revision 1.25 diff -u -r1.25 Socket.php --- Socket.php 15 Nov 2005 03:48:06 -0000 1.25 +++ Socket.php 29 May 2006 01:44:26 -0000 @@ -441,14 +441,17 @@ return $this->raiseError('not connected'); } + ob_start(); $line = ''; $timeout = time() + $this->timeout; while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { - $line .= @fgets($this->fp, $this->lineLength); + $line .= fgets($this->fp, $this->lineLength); if (substr($line, -1) == "\n") { + ob_end_clean(); return rtrim($line, "\r\n"); } } + ob_end_clean(); return $line; }
 [2006-06-02 09:14 UTC] jason dot e dot stewart at gmail dot com
yup, that does the trick for me. without the @fgets(), the error gets propagated. Thanks.
 [2007-04-16 10:28 UTC] mpdude (Matthias Pigulla)
Sorry for complaining so late, but this caught us but now with the release of 1.0.7. Output buffering functions cannot be used in output buffering display handlers. We're using Net_Socket in a callback set up with ob_start() and this now fails. I agree that it is unfortunate that '@' silences fatal errors, so your script just terminates without giving any hint at all what goes wrong (independent of how you set up your error handling/reporting). I also agree that this package should try it's best to prevent warnings from leaking out of it. The problem is that PHP's error handling options are insufficient to solve this issue. Now you might argue that what we're doing is discouraged (and that *we* should fix *our* code). Anyway I recommend reverting the fix from revision 1.26 because it only covers up the symptoms in this particular place. There are lots of places in the package where the same problem needs to be addressed, so it's not a systematic fix. And the approach is not really suitable for suppressing warning messages at a large scale. Another downside is that clients might have set up an error handler and now suddenly find themselves in that handler (due to warnings) with the output buffer still active (and ob_end_clean pending), what might lead to other strange and more-application dependant errors.
 [2007-05-04 04:38 UTC] chagenbu (Chuck Hagenbuch)
Thank you for your bug report. This issue has been fixed in the latest released version of the package, which you can download at http://pear.php.net/get/Net_Socket On reflection, I agree. I've released 1.0.8 which reverts the change and shouldn't cause issues with output buffering. A new major version of Net_Socket can change error handling strategies, but for now, @ is what we've got.