Skip to content

Commit 7454015

Browse files
authored
Merge pull request #9 from php-soap/deal-with-null-responses
Deal with null responses coming back from server
2 parents a5e5f02 + cb808c6 commit 7454015

File tree

8 files changed

+141
-29
lines changed

8 files changed

+141
-29
lines changed

.phive/phars.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phive xmlns="https://phar.io/phive">
3-
<phar name="psalm" version="^4.13.1" installed="4.13.1" location="./tools/psalm.phar" copy="true"/>
3+
<phar name="psalm" version="^4.17" installed="4.17.0" location="./tools/psalm.phar" copy="true"/>
44
<phar name="php-cs-fixer" version="^3.3.2" installed="3.3.2" location="./tools/php-cs-fixer.phar" copy="true"/>
55
</phive>

psalm.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
<psalm
33
errorLevel="2"
44
resolveFromConfigFile="true"
5-
forbidEcho="true"
65
strictBinaryOperands="true"
76
phpVersion="8.0"
87
allowStringToStandInForClass="true"
@@ -19,7 +18,4 @@
1918
<directory name="tests" />
2019
</ignoreFiles>
2120
</projectFiles>
22-
<stubs>
23-
<file name="stubs/SoapClient.phpstub" />
24-
</stubs>
2521
</psalm>

src/AbusedClient.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Soap\Engine\HttpBinding\SoapRequest;
88
use Soap\Engine\HttpBinding\SoapResponse;
9+
use Soap\ExtSoapEngine\ErrorHandling\ExtSoapErrorHandler;
910
use Soap\ExtSoapEngine\Exception\RequestException;
1011
use SoapClient;
1112

@@ -63,7 +64,11 @@ public function doActualRequest(
6364
bool $oneWay = false
6465
): string {
6566
$this->__last_request = $request;
66-
$this->__last_response = (string) parent::__doRequest($request, $location, $action, $version, $oneWay);
67+
$this->__last_response = (string) ExtSoapErrorHandler::handleNullResponse(
68+
ExtSoapErrorHandler::handleInternalErrors(
69+
fn (): ?string => parent::__doRequest($request, $location, $action, $version, $oneWay)
70+
)
71+
);
6772

6873
return $this->__last_response;
6974
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Soap\ExtSoapEngine\ErrorHandling;
5+
6+
use Soap\ExtSoapEngine\Exception\RequestException;
7+
8+
/**
9+
* @psalm-internal Soap\ExtSoapEngine
10+
*/
11+
final class ExtSoapErrorHandler
12+
{
13+
private function __construct()
14+
{
15+
}
16+
17+
/**
18+
* @template T
19+
*
20+
* @param (callable(): T) $fun
21+
*
22+
* @return array{0: T, 1: ?string}
23+
*
24+
* @psalm-suppress MissingThrowsDocblock
25+
*/
26+
public function __invoke(callable $fun): array
27+
{
28+
$lastMessage = null;
29+
/** @psalm-suppress InvalidArgument */
30+
set_error_handler(static function (int $_type, string $message) use (&$lastMessage) {
31+
$lastMessage = $message;
32+
});
33+
34+
try {
35+
$value = $fun();
36+
37+
/** @var array{0: T, 1: ?string} $result */
38+
$result = [$value, $lastMessage];
39+
40+
return $result;
41+
} finally {
42+
restore_error_handler();
43+
}
44+
}
45+
46+
/**
47+
* @template T
48+
*
49+
* @param (callable(): T) $fun
50+
*
51+
* @return T
52+
*/
53+
public static function handleInternalErrors(callable $fun)
54+
{
55+
[$result, $lastMessage] = (new self)($fun);
56+
57+
if ($lastMessage) {
58+
throw RequestException::internalSoapError($lastMessage);
59+
}
60+
61+
return $result;
62+
}
63+
64+
/**
65+
* @template T
66+
*
67+
* @param T $response
68+
* @psalm-assert !null $response
69+
*
70+
* @return T
71+
*/
72+
public static function handleNullResponse($response)
73+
{
74+
if ($response === null) {
75+
throw RequestException::internalSoapError(
76+
'An empty response got returned after contacting the SOAP server.'
77+
);
78+
}
79+
80+
return $response;
81+
}
82+
}

src/Exception/RequestException.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ public static function noRequestWasMadeYet(): self
1111
{
1212
return new self('No request has been registered yet.');
1313
}
14+
15+
public static function internalSoapError(string $lastError): self
16+
{
17+
return new self('Internal ext-soap error: ' . $lastError);
18+
}
1419
}

stubs/SoapClient.phpstub

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace SoapTest\ExtSoapEngine\Unit\ErrorHandling;
5+
6+
use PHPUnit\Framework\TestCase;
7+
use Soap\ExtSoapEngine\ErrorHandling\ExtSoapErrorHandler;
8+
use Soap\ExtSoapEngine\Exception\RequestException;
9+
10+
final class ExtSoapErrorHandlerTest extends TestCase
11+
{
12+
public function test_it_can_deal_with_null_responses(): void
13+
{
14+
$this->expectException(RequestException::class);
15+
16+
ExtSoapErrorHandler::handleNullResponse(null);
17+
}
18+
19+
public function test_it_can_deal_with_non_null_responses(): void
20+
{
21+
$res = ExtSoapErrorHandler::handleNullResponse('hello');
22+
23+
static::assertSame('hello', $res);
24+
}
25+
26+
public function test_it_can_detect_no_internal_errors_during_callback(): void
27+
{
28+
$res = ExtSoapErrorHandler::handleInternalErrors(
29+
static fn () => 'hello'
30+
);
31+
32+
static::assertSame($res, 'hello');
33+
}
34+
35+
public function test_it_can_detect_internal_errors_during_callback(): void
36+
{
37+
$this->expectException(RequestException::class);
38+
$this->expectExceptionMessage('hello');
39+
40+
ExtSoapErrorHandler::handleInternalErrors(
41+
static function () {
42+
trigger_error('hello');
43+
return 'x';
44+
}
45+
);
46+
}
47+
}

tools/psalm.phar

194 KB
Binary file not shown.

0 commit comments

Comments
 (0)