Re: [SOAP] Found error handling problems with PEAR's SOAP_Server
| From: | Will Green | Date: | Mon, 12 Jan 2004 01:47:52 +0000 |
| Subject: | Re: [SOAP] Found error handling problems with PEAR's SOAP_Server | ||
| References: | 1 | Groups: | php.soap |
| Request: | Send a blank email to php-soap+get-1309@lists.php.net to get a copy of this message | ||
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-- William Green President, HotGazpacho Consulting, Inc. 11801 50th St. N #A11 Tampa, FL 33617 813-988-4338 (Office) 813-892-2414 (Mobile)< $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_reportinglevel says so// added by Jon Day <php.soap@jonathanday.com> if ((error_reporting() & $errno) == $errno) {$linenum\n";$detail = "Errno: $errno\nFilename: $filename\nLineno:$detail);// XXX very strange behaviour with error handling if we =& here. $soap_server_fault = new SOAP_Fault($errmsg, 'Server', 'PHP',}239c243< $ret = @call_user_func_array(array(&$this->soapobject,$methodname),$args); ---$methodname),$args); 241c245$ret = call_user_func_array(array(&$this->soapobject,< $ret = @call_user_func_array($methodname,$args);---246c250$ret = call_user_func_array($methodname,$args);< $ret = @call_user_func(array(&$this->soapobject,$methodname)); ---$methodname)); 248c252$ret = call_user_func(array(&$this->soapobject,< $ret = @call_user_func($methodname);---$ret = call_user_func($methodname);