Bug #76070 [Com]: SoapServer::handle() catches some exceptions, but not all
| From: | kontakt at beberlei dot de | Date: | Thu, 28 Feb 2019 19:30:50 +0000 |
| Subject: | Bug #76070 [Com]: SoapServer::handle() catches some exceptions, but not all | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-219773@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76070&edit=1
ID: 76070
Comment by: kontakt at beberlei dot de
Reported by: magnar at myrtveit dot com
Summary: SoapServer::handle() catches some exceptions, but
not all
Status: Open
Type: Bug
Package: SOAP related
Operating System: Windows
PHP Version: 7.1.15
Block user comment: N
Private report: N
New Comment:
This has always been the default behavior when SOAP ran into a fatal error in PHP 5 and it was
ported to PHP 7 when the Error exception was introduced.
In any case you should not let the SoapServer ever take control of the error handling, because you
might want to convert exceptions gracefully into SoapFaults.
I recommend using a proxy object, or function in your case:
$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();
Previous Comments:
------------------------------------------------------------------------
[2018-03-08 18:37:11] magnar at myrtveit dot com
Description:
------------
Sometimes exceptions are caught by SoapServer::handle(), and sometimes not. Particularly, exceptions
of type Error are caught, while exceptions of type Exception are not.
Consider the test script. There are two lines throwing exceptions that are commented out.
By sending a request to the soap server, the file
response.txt is created with the
expected soap response.
By uncommenting the first exception (1) and sending a request to the soap server, the
file exception.txt is created with the following contents:
Uncaught exception: bar
By uncommenting the second exception (2) and sending a request to the soap server, the
file exception.txt is not created! But the file response.txt is created
with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>foo</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
It is surprising that the second exception never reaches the exception handler. Instead, the
exception seems to be caught inside SoapServer::handle(), and the exception message is sent as a
soap fault to the client.
Test script:
---------------
Server script, uncomment the exceptions, one after the other, to see the strange behavior:
<?php
set_exception_handler(function(Throwable $Exception) {
file_put_contents(__DIR__.'/exception.txt', 'Uncaught exception:
'.$Exception->getMessage());
});
function SoapFunction() {
// throw new Exception('bar'); // (1) Invokes the exception handler
// throw new Error('foo'); // (2) Does not invoke the exception handler!
}
$Server = new SoapServer(null, ['uri' => 'MyNamespace']);
$Server->addFunction('SoapFunction');
ob_start();
$Server->handle();
file_put_contents(__DIR__.'/response.txt', ob_get_flush());
Client script, change http://www.example.com/server.php so that it points to
the server script above:
<?php
$Client = new SoapClient(null, ['uri' => 'MyNamespace', 'location'
=> 'http://www.example.com/server.php']);
$Client->__soapCall('SoapFunction', []);
Expected result:
----------------
By uncommenting the second exception (2) and sending a request to the soap server, I
would expect that the file exception.txt was created with the following contents:
Uncaught exception: foo
Actual result:
--------------
By uncommenting the second exception (2) and sending a request to the soap server, the
file response.txt is created with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>foo</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76070&edit=1