RE: Found error handling problems with PEAR's SOAP_Server

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Will:

I agree with your opinion that my code should not generate E_NOTICE errors.
In fact, E_NOTICE errors aren't generated by any of my code.

However, in a practical situation, we must acknowledge that it is incorrect
behavior to catch errors as fatal when the @ error-control operator is used.


This has to do with the way PHP dispatches errors to a custom error handler
(such as SOAP_ServerErrorHandler our case). The PHP manual confirms that
when using a custom error handler, it is up to the custom handler function
to read the current value of error_reporting and act appropriately. It then
goes on to remind you that error-causing statements prepended by the @
error-control operator are ALSO dispatched to the handler - which means the
custom handler should check for it and behave accordingly. 

In the case of the SOAP_ServerErrorHandler, forcing the server to halt
processing whenever an error is occurred despite the use of the @
error-control operator is wrong PHP behavior. Why? It renders php's @
operator completely useless in any soap server built with the pear library!

Yes, it is not the best idea to use the @ error-control operator, however,
its use is *widely* spread across the entire PHP community. Personally, I
never use it - however, you'll notice by looking at the current code of
SOAP_Server.php that it even uses the @ operator for suppressing errors! In
fact, my patch removes the need for SOAP_Server.php to use the operator in
the cases in question by properly handling the errors (as you can see by
looking at the diff submitted at the end of my first message).

You will really feel the pain of the current code if you try using the
standard PEAR::DB_DataObject library with your SOAP server methods for the
simple reason that the @ error-control operator is abundantly used
throughout the PEAR::DB_DataObject code. And the SOAP_Server stops working
because it incorrectly handles "notification" of errors within a
@-controlled block. These aren't even at the E_NOTICE level, they are a
special 0 code - which is intended to allow deep debugging logs to be
created by custom error handlers.

I discovered all this strangeness in the SOAP_Server.php code when trying to
use the standard PEAR::DB_DataObject library (which is now quite widely
accepted).

That PEAR DB library, has approximately 60 instances in just one of its file
where the @ error-control operator is used. AND... because the Soap
Library's SOAP_ServerErrorHandler doesn't check to see how to handle the
error (based on $errno and error_reporting), it halts the server every time
there is an error, even if the developer has specifically requested it not
to.

I think it is better to be consistent with the entire PHP standard, and have
the library conform to the error_handling procedures used throughout PHP and
PEAR; otherwise, this wonderful SOAP library is un-useable with PEAR
DB_DataObject as well as many other well known libraries and tools.

That was a bit of a mouthful, and I hope I didn't scare anyway with such a
dry language.

Cheers -

Jon.




 



-----Original Message-----
From: Will Green [mailto:will@hotgazpacho.com]
Sent: Sunday, January 11, 2004 8:48 PM
To: soap@lists.php.net
Subject: Re:  Found error handling problems with PEAR's SOAP_Server

I am of the opinion that if your code is generating E_NOTICE errors, then
perhaps you need to look at some methods to validate the data you are
handing to the functions that generate the errors.

For example, you gave the example of using file() to read a non-existant
file.  Well, perhaps you might check to see if the file exists (and is
readable) first by calling is_readable.  This will allow you to send a more
intelligent Fault to your clients.

In Java, we'd get around this problem by wrapping the file read operation in
a try/catch block.  You can't do that directly in PHP 4 ( but PHP 5 will
provide this), so you have to sort of simulate this by using other functions
to validate your arguments before hand.

Also, I do believe that an E_NOTICE error should cause a SOAP Fault. 
Something went wrong when your script tried to process the data given to it.
Rather than trying to tell PHP to ignore it, I would suggest that you
instead focus on catching the error in the first place.

==
Will Green

Jon Day wrote:

> Hello There:
>  
> I would like to start out by saying that I am glad that this community 
> exists - and I am very grateful for everyone's contributions. I have 
> just spent the last day in heavy SOAP development with PEAR and 
> discovered a bug/wrinkle that causes major problems when dealing with
error handling.
>  
> In short, the Server.php file's SOAP_ServerErrorHandler function does 
> not check the error_reporting level before it sets $soap_server_fault. 
> This has become very annoying because a simple E_NOTICE error causes 
> the server to return a soap fault!
> 
> My first thought was to use php's error_reporting() feature to ignore 
> E_NOTICE errors, only to realize that the library ignores this setting 
> completely when handling an error (for two reasons: 1. There is no 
> code in the function SOAP_ServerErrorHandler to check the error_reporting
level; 2.
> Even if such code existed, you would have to set 
> error_reporting(E_<blah>) in all your server methods, since your 
> server methods are called by SOAP_Server with the @ symbol, which sets 
> error_reporting to nothing for the scope of the method).
>  
> The PHP manual suggests the following when using custom error handlers:
> "error_reporting() settings will have no effect and your error handler 
> will be called regardless - however you are still able to read the 
> current value of error_reporting and act appropriately. Of particular 
> note is that this value will be 0 if the statement that caused the 
> error was prepended by the @ error-control operator."
>  
> That means that as of right now, if you have a line of code executed 
> that looks like this:
> $file = @file('/path/to/a/non/existant/file');
> .. then your soap server will return a soap fault, regarless of what 
> error_reporting is set to! Even when the above errorsome "file" 
> funciton call is prefixed with the @ symbol!
> How do we solve these issues?
>  
> There are two changes that need to be made to the Server.php file. 
> First, removing the @ error-control operator on all the server method 
> calling code (they are not needed because a custom error handler was 
> set using set_error_handler, which catches errors anyway... so all 
> these symbols actually do is change the error_reporting level in the 
> scope of the called server method. Second is to update the 
> SOAP_ServerErrorHandler callback function to check the level of 
> error_reporting and decide whether or not an error should be logged to 
> the global $soap_server_fault (which is later check for and returned as a
soap fault to the client if set).
>  
> In case you didn't realize yet, I'm referring to the Server.php which 
> has moved to the ZEND_ENGINE_1 branch of cvs. (v1.44.2.1 2003/12/20 
> from CVS). I have a clean patched version of the file for the cvs
maintainer(s) (Shane?).
>  
> Please let me know who I should send the patched file to -
>  
> Any comments welcome!
> 
> Thanks for listening,
>  
> Jon
> 
> PS Below is the result of cvs diff after my modifications for the 
> Server.php file in question:
> 
> ===================================================================
> RCS file: /repository/pear/SOAP/Server.php,v
> retrieving revision 1.44.2.1
> diff -r1.44.2.1 Server.php
> 32,34c32,38
> <     $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);
> ---
> 
>>    // only set the $soap_server_fault global if the the 
>> error_reporting
> 
> level says so
> 
>>    // added by Jon Day <php.soap@jonathanday.com>
>>    if ((error_reporting() & $errno) == $errno) {
>>        $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);
> 
>>    }
> 
> 239c243
> <                 $ret = @call_user_func_array(array(&$this->soapobject,
> $methodname),$args);
> ---
> 
>>                $ret = call_user_func_array(array(&$this->soapobject,
> 
> $methodname),$args);
> 241c245
> <                 $ret = @call_user_func_array($methodname,$args);
> ---
> 
>>                $ret = call_user_func_array($methodname,$args);
> 
> 246c250
> <                 $ret = @call_user_func(array(&$this->soapobject,
> $methodname));
> ---
> 
>>                $ret = call_user_func(array(&$this->soapobject,
> 
> $methodname));
> 248c252
> <                 $ret = @call_user_func($methodname);
> ---
> 
>>                $ret = call_user_func($methodname);
> 
> 

--
William Green
President, HotGazpacho Consulting, Inc.
11801 50th St. N #A11
Tampa, FL 33617

813-988-4338 (Office)
813-892-2414 (Mobile)

--
PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit:
http://www.php.net/unsub.php

-- 
PHP Soap Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [Kernel Newbies]     [PHP Database]     [Yosemite]

  Powered by Linux