Home » Networking » Net_Socket » Bug #7692
readLine exits silently on error
Details
| Submitted | 2006-05-22 10:58 UTC |
|---|---|
| From | jason dot e dot stewart at gmail dot com |
| Assigned | chagenbu |
| Status | Closed |
| Package | Net_Socket |
| PHP Version | 5.0.2 |
| OS | Windows NT |
| Roadmaps | (Not assigned) |
Comments
[2006-05-22 10:58 UTC] jason dot e dot stewart at gmail dot com
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()??
[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
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
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
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.