1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the tarantool/client package. |
5
|
|
|
* |
6
|
|
|
* (c) Eugene Leonovich <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
declare(strict_types=1); |
13
|
|
|
|
14
|
|
|
namespace Tarantool\Client\Tests\Integration; |
15
|
|
|
|
16
|
|
|
use Tarantool\Client\Error; |
17
|
|
|
use Tarantool\Client\Exception\RequestFailed; |
18
|
|
|
|
19
|
|
|
final class BoxErrorTest extends TestCase |
20
|
|
|
{ |
21
|
|
|
public function testExceptionIsThrown() : void |
22
|
|
|
{ |
23
|
|
|
$this->expectException(RequestFailed::class); |
24
|
|
|
$this->expectExceptionMessage('Because I can'); |
25
|
|
|
$this->expectExceptionCode(42); |
26
|
|
|
|
27
|
|
|
$this->client->evaluate('box.error({code = 42, reason = "Because I can"})'); |
|
|
|
|
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @requires Tarantool >=2.4.1 |
32
|
|
|
*/ |
33
|
|
|
public function testExceptionWithErrorIsThrown() : void |
34
|
|
|
{ |
35
|
|
|
try { |
36
|
|
|
/* |
37
|
|
|
* Triggers "AccessDeniedError", which includes the fields |
38
|
|
|
* "object_type", "object_name", "access_type", "user" (since 3.1). |
39
|
|
|
* See https://www.tarantool.io/en/doc/2.4/dev_guide/internals/box_protocol/#binary-protocol-responses-for-errors-extra. |
40
|
|
|
*/ |
41
|
|
|
$this->client->evaluate(" |
42
|
|
|
local temp_user = 'user_with_no_privileges' |
43
|
|
|
local curr_user = box.session.user() |
44
|
|
|
box.schema.user.create(temp_user) |
45
|
|
|
box.session.su(temp_user) |
46
|
|
|
local _, err = pcall(box.schema.user.grant, temp_user, 'execute', 'universe') |
47
|
|
|
box.session.su(curr_user) |
48
|
|
|
box.schema.user.drop(temp_user) |
49
|
|
|
box.error(err) |
50
|
|
|
"); |
51
|
|
|
self::fail(sprintf('"%s" exception was not thrown', RequestFailed::class)); |
52
|
|
|
} catch (RequestFailed $e) { |
53
|
|
|
self::assertSame("Write access to space '_priv' is denied for user 'user_with_no_privileges'", $e->getMessage()); |
54
|
|
|
self::assertSame(42, $e->getCode()); |
55
|
|
|
|
56
|
|
|
$error = $e->getError(); |
57
|
|
|
self::assertInstanceOf(Error::class, $error); |
58
|
|
|
self::assertSame('AccessDeniedError', $error->getType()); |
59
|
|
|
self::assertSame("Write access to space '_priv' is denied for user 'user_with_no_privileges'", $error->getMessage()); |
60
|
|
|
self::assertSame(42, $error->getCode()); |
61
|
|
|
$expectedFields = [ |
62
|
|
|
'object_type' => 'space', |
63
|
|
|
'object_name' => '_priv', |
64
|
|
|
'access_type' => 'Write', |
65
|
|
|
'user' => 'user_with_no_privileges', |
66
|
|
|
]; |
67
|
|
|
if ($this->tarantoolVersionSatisfies('< 3.1')) { |
68
|
|
|
unset($expectedFields['user']); |
69
|
|
|
} |
70
|
|
|
self::assertEquals($expectedFields, $error->getFields()); |
71
|
|
|
self::assertNull($error->getPrevious()); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @requires Tarantool >=2.4.1 |
77
|
|
|
*/ |
78
|
|
|
public function testExceptionWithNestedErrorIsThrown() : void |
79
|
|
|
{ |
80
|
|
|
try { |
81
|
|
|
$this->client->evaluate(' |
82
|
|
|
err1 = box.error.new({code = 1, type = "t1", reason = "r1"}) |
83
|
|
|
err2 = box.error.new({code = 2, type = "t2", reason = "r2",}) |
84
|
|
|
err1:set_prev(err2) |
85
|
|
|
box.error(err1) |
86
|
|
|
'); |
87
|
|
|
self::fail(sprintf('"%s" exception was not thrown', RequestFailed::class)); |
88
|
|
|
} catch (RequestFailed $e) { |
89
|
|
|
self::assertSame('r1', $e->getMessage()); |
90
|
|
|
self::assertSame(1, $e->getCode()); |
91
|
|
|
|
92
|
|
|
$error = $e->getError(); |
93
|
|
|
self::assertInstanceOf(Error::class, $error); |
94
|
|
|
self::assertSame('CustomError', $error->getType()); |
95
|
|
|
self::assertSame('r1', $error->getMessage()); |
96
|
|
|
self::assertSame(1, $error->getCode()); |
97
|
|
|
self::assertSame(['custom_type' => 't1'], $error->getFields()); |
98
|
|
|
|
99
|
|
|
$prevError = $error->getPrevious(); |
100
|
|
|
self::assertInstanceOf(Error::class, $prevError); |
101
|
|
|
self::assertSame('CustomError', $prevError->getType()); |
102
|
|
|
self::assertSame('r2', $prevError->getMessage()); |
103
|
|
|
self::assertSame(2, $prevError->getCode()); |
104
|
|
|
self::assertSame(['custom_type' => 't2'], $prevError->getFields()); |
105
|
|
|
self::assertNull($prevError->getPrevious()); |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.