Zend SOAP server: what is the best approach for error/exception handling?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Zend SOAP server: what is the best approach for error/exception handling?

James Gordon
I have a class called Foo that is exposed as a Web Service using Zend_Soap_Server, in the usual way, eg:

$server = new Zend_Soap_Server(APPLICATION_PATH . '/foo/wsdl');
$server->setClass('Foo');
$server->handle();

On normal execution, any method of the Foo class that is called by SOAP clients runs successfully and the appropriate XML document is returned to the client courtesy of Zend_Soap_Server.

My question, however, is this: What is the best approach to handling abnormal execution? Eg. the client supplies an invalid parameter when calling one of Foo's methods via SOAP?

As I understand it, the correct behaviour in this situation is for the SOAP server to send back a document to the client detailing the fault. The two key fields in this document are faultcode and faultstring.

The only solution I've found so far that achieves this is to have Foo's methods throw SoapFault() exceptions when they encounter problems. However, I'm not fond of this approach because:

1. This means Foo has knowledge about how it is being exposed to the outside world (SOAP), which, ideally, it should not have, both for idealistic OO design reasons and practical testing reasons.

2. Throwing a generic Exception doesn't work because the faultcode and faultstring don't get passed back to the client.

3. Throwing a Zend_Soap_Server_Exception doesn't work either, because it simply inherits from Zend_Exception, which inherits from Exception, so the behaviour is identical to the previous point.

BTW - I should point out that I'm using Zend Framework 1.7.6.

If anybody has any words of wisdom they could offer on this topic, I would be most grateful.
Reply | Threaded
Open this post in threaded view
|

Re: Zend SOAP server: what is the best approach for error/exception handling?

Benjamin Eberlei-2

The Zend Soap Server internally catches all exceptions, warnings and
notices and transforms them
into XML SOAP Fault Response MEssages which are sent back to the client.

You can even decide which Error Messages are taken from the Exception based
on the Exception type with $server->registerException() // or something
like that.

greetings,
Benjamin

On Wed, 11 Mar 2009 17:56:10 -0700 (PDT), James Gordon
<[hidden email]> wrote:

>
> I have a class called Foo that is exposed as a Web Service using
> Zend_Soap_Server, in the usual way, eg:
>
> $server = new Zend_Soap_Server(APPLICATION_PATH . '/foo/wsdl');
> $server->setClass('Foo');
> $server->handle();
>
> On normal execution, any method of the Foo class that is called by SOAP
> clients runs successfully and the appropriate XML document is returned to
> the client courtesy of Zend_Soap_Server.
>
> My question, however, is this: What is the best approach to handling
> abnormal execution? Eg. the client supplies an invalid parameter when
> calling one of Foo's methods via SOAP?
>
> As I understand it, the correct behaviour in this situation is for the
> SOAP
> server to send back a document to the client detailing the fault. The two
> key fields in this document are faultcode and faultstring.
>
> The only solution I've found so far that achieves this is to have Foo's
> methods throw SoapFault() exceptions when they encounter problems.
> However,
> I'm not fond of this approach because:
>
> 1. This means Foo has knowledge about how it is being exposed to the
> outside
> world (SOAP), which, ideally, it should not have, both for idealistic OO
> design reasons and practical testing reasons.
>
> 2. Throwing a generic Exception doesn't work because the faultcode and
> faultstring don't get passed back to the client.
>
> 3. Throwing a Zend_Soap_Server_Exception doesn't work either, because it
> simply inherits from Zend_Exception, which inherits from Exception, so
the
> behaviour is identical to the previous point.
>
> BTW - I should point out that I'm using Zend Framework 1.7.6.
>
> If anybody has any words of wisdom they could offer on this topic, I
would
> be most grateful.
> --
> View this message in context:
>
http://www.nabble.com/Zend-SOAP-server%3A-what-is-the-best-approach-for-error-exception-handling--tp22467835p22467835.html
> Sent from the Zend Web Services mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Zend SOAP server: what is the best approach for error/exception handling?

James Gordon
Hi Benjamin,

Although your comments didn't correlate with my initial test results, I realised they may have been skewed by the rest of the application infrastructure, so I decided to write a stand-alone module to test the various options. I have posted the code below in the hope that it helps somebody else who is trying to figure this out.

The short answer is that trigger_error('Some message', E_USER_ERROR) seems to be the best approach, as it results in a SOAP Fault document being passed back to the client without requiring any SOAP-specific code in the class whose functionality is being exposed, which is pretty much what I wanted. Unfortunately this solution doesn't provide the facility to return an error code, but I'm not too fussed about that.

FWIW, here is my test code:

<?php
/* zstest.php - Simple module to test Zend_Soap_Server error handling behaviour */
set_include_path( '../ws/library/' . get_include_path());
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();

if ( isset($_GET['wsdl'])) {
    $auto = new Zend_Soap_AutoDiscover();
    $auto->setClass('Foo');
    $auto->handle();
} else if ( isset($_GET['ping'])) {
    $client = new Zend_Soap_Client('http://localhost/zstest.php?wsdl');
    try {
        echo $client->ping('Hello World!'), '<br />';
    } catch ( Exception $e ) {
        echo 'Exception caught: ', $e->faultcode , ' - ', $e->faultstring, '<br />';
    }
    echo htmlentities($client->getLastResponse());
} else {
    $server = new Zend_Soap_Server('http://localhost/zstest.php?wsdl');
    $server->setClass('Foo');
    $server->handle();
}

class Foo
{
    /**
     * @param string $testData
     * @return string
     */
    public function ping( $testData )
    {
//        throw new SoapFault( '1', 'Die' ); /* Error code and message passed back in SOAP Fault document. */
//        die( 'Die' ); /* SOAP Fault document is NOT returned by server. */
//        trigger_error('Die', E_USER_ERROR); /* Best compromise. */
        return $testData;
    }
}

?>
beberlei wrote
The Zend Soap Server internally catches all exceptions, warnings and
notices and transforms them
into XML SOAP Fault Response MEssages which are sent back to the client.

You can even decide which Error Messages are taken from the Exception based
on the Exception type with $server->registerException() // or something
like that.

greetings,
Benjamin