Home » Web Services » SOAP » Bug #604
E_NOTICE errors result in no output
Details
| Submitted | 2004-01-21 17:10 UTC |
|---|---|
| From | ajf at roundpoint dot com |
| Assigned | yunosh |
| Status | Closed |
| Package | SOAP |
| PHP Version | 4.3.2 |
| OS | Linux RedHat 7.2 |
| Roadmaps | (Not assigned) |
Comments
[2004-01-21 17:10 UTC] ajf at roundpoint dot com
Description:
------------
An E_NOTICE error, eg for an uninitialised variable, in a SOAP server causes the Apache process to either run at 100% until max_execution_time is reached, or to die with a segmentation fault. The server function completes and the Apache access log records a 200 result, but the client sees either no response when the process has run to the full time, or a bad HTTP response after a segfault.
The problem is seen regardless of the error_reporting() setting but a local error handler set and restored around the offending code will allow the expected result.
Reproduce code:
---------------
Minimal client (client1.php) and server (crashy.php) in http://falmouth.roundpoint.co.uk/~ajf/example.tar.gz reproduces the running till max_execution_time reached case.
Expected result:
----------------
Either the string "Hello stuff" or a soap_fault object regarding the uninitialised variable depending on the level set by error_reporting().
Actual result:
--------------
Either a soap_fault object for a timed out read from the server or for a bad HTTP response.
[2004-04-23 06:15 UTC] lux at simian dot ca
To build on Alan's fix, this would also skip E_NOTICE messages. Not sure the PEAR way (or likely even the best way) to actually do this, but the following at least works.
function SOAP_ServerErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
if (! $errno || $errno == E_NOTICE) {
return;
}
global $soap_server_fault;
$detail = "Errno: $errno\nFilename: $filename\nLineno: $linenum\n";
// XXX very strange behaviour with error handling if we =& here.
$soap_server_fault = new SOAP_Fault($errmsg, 'Server', 'PHP', $detail);
}
[2004-05-07 02:46 UTC] bas at vanklinkenbergsoftware dot nl
The segfault or max. exec. time-out occurs due to Pear::SOAP trying to serialize a recursive array or object, which causes the crash (I will file this as a separate bug).
This recursive array is created due to a backtrace array, which is included in the SOAP_Fault object that gets created due to an E_NOTICE error.
(see line 69 in Fault.php in the 0.8RC3 release (function SOAP_Fault->message())
Appearantly the $this->backtrace variable is assumed to be a string, but isn't really.
An easy (dirty) fix would be to use print_r to change the backtrace array into a string (print_r catches recursion in arrays or objects), like this:
(line 69 would change from:)
$params[] =& new SOAP_Value('detail', 'string', $this->backtrace);
(into:)
$params[] =& new SOAP_Value('detail', 'string', print_r($this->backtrace, true));
A clean (and much tougher) fix would be to make sure recursive arrays or objects are caught in the serialize routines and properly dealt with (probably by throwing a SOAP_Fault - I don't know if the SOAP spec provides in this).