Skip to content

Commit

Permalink
Deal with null responses coming back from server
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Jan 28, 2022
1 parent 66d669f commit cb808c6
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="psalm" version="^4.13.1" installed="4.13.1" location="./tools/psalm.phar" copy="true"/>
<phar name="psalm" version="^4.17" installed="4.17.0" location="./tools/psalm.phar" copy="true"/>
<phar name="php-cs-fixer" version="^3.3.2" installed="3.3.2" location="./tools/php-cs-fixer.phar" copy="true"/>
</phive>
4 changes: 0 additions & 4 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<psalm
errorLevel="2"
resolveFromConfigFile="true"
forbidEcho="true"
strictBinaryOperands="true"
phpVersion="8.0"
allowStringToStandInForClass="true"
Expand All @@ -19,7 +18,4 @@
<directory name="tests" />
</ignoreFiles>
</projectFiles>
<stubs>
<file name="stubs/SoapClient.phpstub" />
</stubs>
</psalm>
7 changes: 6 additions & 1 deletion src/AbusedClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Soap\Engine\HttpBinding\SoapRequest;
use Soap\Engine\HttpBinding\SoapResponse;
use Soap\ExtSoapEngine\ErrorHandling\ExtSoapErrorHandler;
use Soap\ExtSoapEngine\Exception\RequestException;
use SoapClient;

Expand Down Expand Up @@ -63,7 +64,11 @@ public function doActualRequest(
bool $oneWay = false
): string {
$this->__last_request = $request;
$this->__last_response = (string) parent::__doRequest($request, $location, $action, $version, $oneWay);
$this->__last_response = (string) ExtSoapErrorHandler::handleNullResponse(
ExtSoapErrorHandler::handleInternalErrors(
fn (): ?string => parent::__doRequest($request, $location, $action, $version, $oneWay)
)
);

return $this->__last_response;
}
Expand Down
82 changes: 82 additions & 0 deletions src/ErrorHandling/ExtSoapErrorHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);

namespace Soap\ExtSoapEngine\ErrorHandling;

use Soap\ExtSoapEngine\Exception\RequestException;

/**
* @psalm-internal Soap\ExtSoapEngine
*/
final class ExtSoapErrorHandler
{
private function __construct()
{
}

/**
* @template T
*
* @param (callable(): T) $fun
*
* @return array{0: T, 1: ?string}
*
* @psalm-suppress MissingThrowsDocblock
*/
public function __invoke(callable $fun): array
{
$lastMessage = null;
/** @psalm-suppress InvalidArgument */
set_error_handler(static function (int $_type, string $message) use (&$lastMessage) {
$lastMessage = $message;
});

try {
$value = $fun();

/** @var array{0: T, 1: ?string} $result */
$result = [$value, $lastMessage];

return $result;
} finally {
restore_error_handler();
}
}

/**
* @template T
*
* @param (callable(): T) $fun
*
* @return T
*/
public static function handleInternalErrors(callable $fun)
{
[$result, $lastMessage] = (new self)($fun);

if ($lastMessage) {
throw RequestException::internalSoapError($lastMessage);
}

return $result;
}

/**
* @template T
*
* @param T $response
* @psalm-assert !null $response
*
* @return T
*/
public static function handleNullResponse($response)
{
if ($response === null) {
throw RequestException::internalSoapError(
'An empty response got returned after contacting the SOAP server.'
);
}

return $response;
}
}
5 changes: 5 additions & 0 deletions src/Exception/RequestException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ public static function noRequestWasMadeYet(): self
{
return new self('No request has been registered yet.');
}

public static function internalSoapError(string $lastError): self
{
return new self('Internal ext-soap error: ' . $lastError);
}
}
23 changes: 0 additions & 23 deletions stubs/SoapClient.phpstub

This file was deleted.

47 changes: 47 additions & 0 deletions tests/Unit/ErrorHandling/ExtSoapErrorHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);

namespace SoapTest\ExtSoapEngine\Unit\ErrorHandling;

use PHPUnit\Framework\TestCase;
use Soap\ExtSoapEngine\ErrorHandling\ExtSoapErrorHandler;
use Soap\ExtSoapEngine\Exception\RequestException;

final class ExtSoapErrorHandlerTest extends TestCase
{
public function test_it_can_deal_with_null_responses(): void
{
$this->expectException(RequestException::class);

ExtSoapErrorHandler::handleNullResponse(null);
}

public function test_it_can_deal_with_non_null_responses(): void
{
$res = ExtSoapErrorHandler::handleNullResponse('hello');

static::assertSame('hello', $res);
}

public function test_it_can_detect_no_internal_errors_during_callback(): void
{
$res = ExtSoapErrorHandler::handleInternalErrors(
static fn () => 'hello'
);

static::assertSame($res, 'hello');
}

public function test_it_can_detect_internal_errors_during_callback(): void
{
$this->expectException(RequestException::class);
$this->expectExceptionMessage('hello');

ExtSoapErrorHandler::handleInternalErrors(
static function () {
trigger_error('hello');
return 'x';
}
);
}
}
Binary file modified tools/psalm.phar
Binary file not shown.

0 comments on commit cb808c6

Please sign in to comment.