php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36629 SoapServer::handle() exits on SOAP faults
Submitted: 2006-03-06 13:50 UTC Modified: 2006-03-10 12:49 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: ilya at iponweb dot net Assigned: dmitry (profile)
Status: Closed Package: SOAP related
PHP Version: 5CVS-2006-03-06 (snap) OS: Debian Linux (testing)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ilya at iponweb dot net
New email:
PHP Version: OS:

 

 [2006-03-06 13:50 UTC] ilya at iponweb dot net
Description:
------------
When calling SoapServer::handle() it exits after processing the SOAP request if request handler returns a SoapFault object. It makes impossible to do any work on the SOAP server side after processing requests if they result in SoapFault.

I belive exactly the same issue was reported in bug report #31993 but for some reason it was closed without actually fixing the problem in the soap extension. I could reproduce the problem with PHP 5.1.1 and with PHP snapshot 5.1-200603061130.

The test code demostrates this problem. It is a simple soap server with two remotly callable functions: test1 and test2. The first of them simply returns a string, the second returns a soap fault object. The server is supposed to write a string to a log file after processing a request. If you call remotly test1 function then you can see the string in the log, if you call remotly test2 function then the log file is empty.

Reproduce code:
---------------
<?php

$server = new SoapServer(null, array('uri' => "http://test-uri/"));

$h = fopen("/tmp/soap.log", "w");

$server->addFunction(array('test1', 'test2'));
$server->handle();

fputs($h, 'TEST');
fclose($h);

function test1() {
	return "test1";
}

function test2() {
	return new SoapFault("test2", "test2");
}

?>

Expected result:
----------------
A log message in file /tmp/soap.log

Actual result:
--------------
Nothing when calling remotly 'test2' function.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-10 12:49 UTC] dmitry@php.net
Fixed in CVS HEAD and PHP_5_1.
 [2010-03-19 03:13 UTC] druidmatrix at yahoo dot com
I am still having this problem on Fedora Core 10.  PHP is:
[csit@fc10-test webservices]$ php -v
PHP 5.2.11 (cli) (built: Jan  4 2010 23:45:34)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies

I am not able to catch the SoapFault on the server side at all - not even by using a try-catch around $server->handle().  It looks like the server is immediately generating the SoapFault and returning it to the client; control never advances beyond the handle() call on the server side.
 [2011-03-21 15:23 UTC] leon at fun4me dot demon dot nl
I am still having this problem.
I don't think this is solved


I am using 
PHP/5.3.3-1ubuntu9.3

When using SoapServer in WSDL-mode and let it handle a request which does not match the wsdl I get a SOAP-ENV:Fault directly in my soap-client (AND sometimes a stack-trace! which is really problematic). I am not able to intercept this fault-response (let alone the stacktrace) in php (with try/catch and ob_get_clean)


class SoapServerAdapter implements SoapProcessor
{
  
  /**
   * The soapServer instance
   *
   * @var SoapServer
   */
  protected $soapServer;
  
  /**
   * @param SoapServer $soapServer
   */
  public function __construct(SoapServer $soapServer)
  {
    $this->soapServer = $soapServer;
  }
  
  /*
   * Call the configured soap server, return the generated response.
   */
  public function process(sfWebRequest $request)
  {
    ob_start();
      $this->soapServer->handle($request->getContent());
    $responseMessage = ob_get_clean();

    return 'intercepted with ob_get: '.$responseMessage;
  }
}


public function handle(sfWebRequest $request) 
{
    $soapServer = new SoapServer($this->wsdl);
    $soapProcessor = new SoapProcessor($soapServer);

    try
    {
      $response = $soapProcessor->process($request);

      echo $response;
    }
    catch (Exception $e)
    {
      // TODO: handle errors, like 404
      die('unforntunately I never get here!);
    }
}
 [2011-03-21 15:52 UTC] leon at fun4me dot demon dot nl
Regarding the fatal Error, 

this happens specifically when calling a procedure, not defined in the wsdl (although I sometimes do get a soap-env:fault in return). Restarting apache solves the fatal, however it should not happen at all of course! 

Ps. I want to catch these soap-Faults because I want to add WS-A and WS-S headers and want to do some logging afterwards.


A strack trace of the fatal:


Fatal error: Procedure 'NonExistingProcedureFromSoapRequestMessage' not present in /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/WebService/new/soSoapServerAdapter.php on line 28

Call Stack:
    0.0000     636712   1. {main}() /home/leree/workspace/trunk/symfony/web/services_dev.php:0
    0.0270    3826776   2. sfContext->dispatch() /home/leree/workspace/trunk/symfony/web/services_dev.php:15
    0.0270    3826856   3. soSoapController->dispatch() /home/leree/workspace/trunk/symfony/lib/vendor/symfony/lib/util/sfContext.class.php:170
    0.0345    4159040   4. soSoapTrafficLogInterceptor->process() /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/controller/soSoapController.class.php:34
    0.0348    4159792   5. soSoapWsaInterceptor->process() /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/WebService/new/soSoapTrafficLogInterceptor.php:18
    0.0354    4160744   6. soSoapAdapterResolver->process() /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/WebService/new/soSoapWsaInterceptor.php:51
    0.0354    4160880   7. soSoapServerAdapter->process() /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/WebService/new/soSoapAdapterResolver.php:30
    0.0354    4202736   8. SoapServer->handle() /home/leree/workspace/trunk/symfony/plugins/soSoapServerPlugin/lib/WebService/new/soSoapServerAdapter.php:28



line 28 of this soapServerAdapter is the line where I call:
  $this->soapServer->handle($request->getContent());

wrapped in the ob_start/ob_get_clean functions
 [2012-04-20 14:37 UTC] guillaume dot outters at smile dot fr
Maybe the "solution" given in bug 50547 solves the problem (calling xdebug_disable() before SoapServer::handle())?
https://bugs.php.net/bug.php?id=50547#1298563236
(third comment)
 [2020-05-05 11:56 UTC] php at maketime dot nl
This bug is still active in PHP 7.2.24

In my case a SoapFault is returned because of a not understood soap header in the POST-ed soap body and I can't do anything after handle(). I don't have xdebug running.

<?php 
ob_start();
$soapServer->handle();

// do something like logging, but this will only work as long as there no SoapFault

return ob_get_clean();
?>

Expected result : 
When a SoapFault occurs, code after handle() should be excecuted.

Actual result : 
Code is not executed after handel(), instead the soapFault body and headers get returned as a response.
 [2020-05-05 12:30 UTC] php at maketime dot nl
I found a workaround for my case in the first comment on this bug : https://bugs.php.net/bug.php?id=76070

The takeway is that you create a proxy with the magic __call method in the class/object handling the soap calls and catch any "normal" errors and converting them to soapFaults yourself and suddenly I can do stuff after handle() when any type of error occurs. 

I will copy paste the code here : 

$server = new SOAPServer(null, ['uri' => 'http://localhost/soap.php', 'location' => 'http://localhost/soap.php']);

class SoapErrorProxy {
    public function __call($function, $args) {
        if (!in_array($function, ['SoapFunction'])) {
            throw new SoapFault('CLIENT', 'function doesnt exist');
        }

        try {
            $function(...$args);
        } catch (Throwable $e) {
            throw new SoapFault('SERVER', 'Internal Error');
        }
    }
}

$server->setObject(new SoapErrorProxy());
$server->handle();

// now code after handle() is reached and executed no matter what type of error
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC