Skip to content

Commit 34d2de1

Browse files
committed
Merge pull request #59 from Timandes/exceptions
Support exceptions.
2 parents e9a97ba + b37eee7 commit 34d2de1

28 files changed

+348
-76
lines changed

config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ if test "$PHP_ZOOKEEPER" != "no"; then
104104
PHP_ADD_LIBRARY_WITH_PATH(zookeeper_mt, $PHP_LIBZOOKEEPER_DIR/lib, ZOOKEEPER_SHARED_LIBADD)
105105

106106
PHP_SUBST(ZOOKEEPER_SHARED_LIBADD)
107-
PHP_NEW_EXTENSION(zookeeper, php_zookeeper.c zoo_lock.c $SESSION_EXTRA_FILES, $ext_shared,,$SESSION_INCLUDES)
107+
PHP_NEW_EXTENSION(zookeeper, php_zookeeper.c zoo_lock.c $SESSION_EXTRA_FILES php_zookeeper_exceptions.c, $ext_shared,,$SESSION_INCLUDES)
108108

109109
fi
110110

php_zookeeper.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "php_zookeeper.h"
4141
#include "php_zookeeper_private.h"
4242
#include "php_zookeeper_session.h"
43+
#include "php_zookeeper_exceptions.h"
4344

4445
/****************************************
4546
Helper macros
@@ -51,7 +52,7 @@
5152
#define ZK_METHOD_FETCH_OBJECT \
5253
i_obj = (php_zk_t *) zend_object_store_get_object( object TSRMLS_CC ); \
5354
if (!i_obj->zk) { \
54-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zookeeper connect was not called"); \
55+
php_zk_throw_exception(PHPZK_CONNECT_NOT_CALLED TSRMLS_CC); \
5556
return; \
5657
} \
5758

@@ -115,6 +116,7 @@ static void php_zookeeper_connect_impl(INTERNAL_FUNCTION_PARAMETERS, char *host,
115116
php_cb_data_t *cb_data = NULL;
116117

117118
if (recv_timeout <= 0) {
119+
php_zk_throw_exception(ZBADARGUMENTS TSRMLS_CC);
118120
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recv_timeout parameter has to be greater than 0");
119121
ZVAL_NULL(object);
120122
return;
@@ -129,7 +131,7 @@ static void php_zookeeper_connect_impl(INTERNAL_FUNCTION_PARAMETERS, char *host,
129131
recv_timeout, 0, cb_data, 0);
130132

131133
if (zk == NULL) {
132-
php_error_docref(NULL TSRMLS_CC, E_ERROR, "could not init zookeeper instance");
134+
php_zk_throw_exception(PHPZK_CONNECTION_FAILURE TSRMLS_CC);
133135
/* not reached */
134136
ZVAL_NULL(object);
135137
return;
@@ -220,7 +222,7 @@ static PHP_METHOD(Zookeeper, create)
220222
realpath, realpath_max);
221223
if (status != ZOK) {
222224
efree(realpath);
223-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
225+
php_zk_throw_exception(status TSRMLS_CC);
224226
return;
225227
}
226228

@@ -248,7 +250,7 @@ static PHP_METHOD(Zookeeper, delete)
248250

249251
status = zoo_delete(i_obj->zk, path, version);
250252
if (status != ZOK) {
251-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
253+
php_zk_throw_exception(status TSRMLS_CC);
252254
return;
253255
}
254256

@@ -284,7 +286,7 @@ static PHP_METHOD(Zookeeper, getChildren)
284286
cb_data, &strings);
285287
if (status != ZOK) {
286288
php_cb_data_destroy(&cb_data);
287-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
289+
php_zk_throw_exception(status TSRMLS_CC);
288290
return;
289291
}
290292

@@ -328,7 +330,7 @@ static PHP_METHOD(Zookeeper, get)
328330

329331
if (status != ZOK) {
330332
php_cb_data_destroy(&cb_data);
331-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
333+
php_zk_throw_exception(status TSRMLS_CC);
332334
return;
333335
}
334336
length = stat.dataLength;
@@ -347,7 +349,7 @@ static PHP_METHOD(Zookeeper, get)
347349
if (status != ZOK) {
348350
efree (buffer);
349351
php_cb_data_destroy(&cb_data);
350-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
352+
php_zk_throw_exception(status TSRMLS_CC);
351353

352354
/* Indicate data marshalling failure with boolean false so that user can retry */
353355
if (status == ZMARSHALLINGERROR) {
@@ -397,7 +399,7 @@ static PHP_METHOD(Zookeeper, exists)
397399
cb_data, &stat);
398400
if (status != ZOK && status != ZNONODE) {
399401
php_cb_data_destroy(&cb_data);
400-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
402+
php_zk_throw_exception(status TSRMLS_CC);
401403
return;
402404
}
403405

@@ -437,7 +439,7 @@ static PHP_METHOD(Zookeeper, set)
437439
}
438440
status = zoo_set2(i_obj->zk, path, value, value_len, version, stat_ptr);
439441
if (status != ZOK) {
440-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
442+
php_zk_throw_exception(status TSRMLS_CC);
441443
return;
442444
}
443445

@@ -490,7 +492,7 @@ static PHP_METHOD(Zookeeper, getAcl)
490492

491493
status = zoo_get_acl(i_obj->zk, path, &aclv, &stat);
492494
if (status != ZOK) {
493-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
495+
php_zk_throw_exception(status TSRMLS_CC);
494496
return;
495497
}
496498

@@ -527,7 +529,7 @@ static PHP_METHOD(Zookeeper, setAcl)
527529
status = zoo_set_acl(i_obj->zk, path, version, &aclv);
528530
php_aclv_destroy(&aclv);
529531
if (status != ZOK) {
530-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
532+
php_zk_throw_exception(status TSRMLS_CC);
531533
return;
532534
}
533535
RETURN_TRUE;
@@ -640,7 +642,7 @@ static PHP_METHOD(Zookeeper, addAuth)
640642
status = zoo_add_auth(i_obj->zk, scheme, cert, cert_len,
641643
(fci.size != 0) ? php_zk_completion_marshal : NULL, cb_data);
642644
if (status != ZOK) {
643-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error: %s", zerror(status));
645+
php_zk_throw_exception(status TSRMLS_CC);
644646
return;
645647
}
646648

@@ -1232,6 +1234,9 @@ PHP_MINIT_FUNCTION(zookeeper)
12321234
#ifdef HAVE_ZOOKEEPER_SESSION
12331235
php_session_register_module(ps_zookeeper_ptr);
12341236
#endif
1237+
1238+
php_zk_register_exceptions(TSRMLS_C);
1239+
12351240
return SUCCESS;
12361241
}
12371242
/* }}} */

php_zookeeper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ PS_FUNCS(zookeeper);
6969

7070
#endif /* HAVE_ZOOKEEPER_SESSION */
7171

72+
#define PHPZK_CONNECTION_FAILURE 5999
73+
#define PHPZK_CONNECT_NOT_CALLED 5998
74+
7275
#endif /* PHP_ZOOKEEPER_H */
7376

7477

php_zookeeper_exceptions.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) 2010 The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| http://www.php.net/license/3_01.txt. |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| license@php.net so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Ryan Uber <ru@ryanuber.com> |
14+
| Timandes White <timands@gmail.com> |
15+
+----------------------------------------------------------------------+
16+
*/
17+
18+
#include <php.h>
19+
20+
#ifdef ZTS
21+
#include "TSRM.h"
22+
#endif
23+
24+
#include "php_zookeeper.h"
25+
#include "php_zookeeper_exceptions.h"
26+
27+
void php_zk_register_exceptions(TSRMLS_D)
28+
{
29+
zend_class_entry ce;
30+
31+
INIT_CLASS_ENTRY(ce, "ZookeeperException", NULL);
32+
zk_base_exception = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
33+
34+
INIT_CLASS_ENTRY(ce, "ZookeeperOperationTimeoutException", NULL);
35+
zk_optimeout_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
36+
37+
INIT_CLASS_ENTRY(ce, "ZookeeperConnectionException", NULL);
38+
zk_connection_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
39+
40+
INIT_CLASS_ENTRY(ce, "ZookeeperMarshallingException", NULL);
41+
zk_marshalling_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
42+
43+
INIT_CLASS_ENTRY(ce, "ZookeeperAuthenticationException", NULL);
44+
zk_auth_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
45+
46+
INIT_CLASS_ENTRY(ce, "ZookeeperSessionException", NULL);
47+
zk_session_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
48+
49+
INIT_CLASS_ENTRY(ce, "ZookeeperNoNodeException", NULL);
50+
zk_nonode_exception = zend_register_internal_class_ex(&ce, zk_base_exception, "ZookeeperException" TSRMLS_CC);
51+
}
52+
53+
zend_class_entry * php_zk_get_exception_with_message(zend_class_entry *ce, char *message TSRMLS_DC)
54+
{
55+
zend_declare_property_string(ce, "message", strlen("message"), message, ZEND_ACC_PUBLIC TSRMLS_CC);
56+
return ce;
57+
}
58+
59+
void php_zk_throw_exception(int zk_status TSRMLS_DC)
60+
{
61+
zend_class_entry *ce;
62+
char *message = NULL;
63+
64+
switch(zk_status) {
65+
case PHPZK_CONNECTION_FAILURE:
66+
ce = zk_connection_exception;
67+
message = "Failed to connect to Zookeeper";
68+
break;
69+
case PHPZK_CONNECT_NOT_CALLED:
70+
ce = zk_connection_exception;
71+
message = "Zookeeper->connect() was not called";
72+
break;
73+
case ZCONNECTIONLOSS:
74+
ce = zk_connection_exception;
75+
break;
76+
case ZOPERATIONTIMEOUT:
77+
ce = zk_optimeout_exception;
78+
break;
79+
case ZMARSHALLINGERROR:
80+
ce = zk_marshalling_exception;
81+
break;
82+
case ZNOAUTH:
83+
case ZAUTHFAILED:
84+
ce = zk_auth_exception;
85+
break;
86+
case ZSESSIONEXPIRED:
87+
case ZSESSIONMOVED:
88+
ce = zk_session_exception;
89+
break;
90+
case ZNONODE:
91+
ce = zk_nonode_exception;
92+
break;
93+
default:
94+
ce = zk_base_exception;
95+
break;
96+
}
97+
98+
if (!message) {
99+
message = (char *)zerror(zk_status);
100+
}
101+
102+
zend_throw_exception(php_zk_get_exception_with_message(ce, message TSRMLS_CC), NULL, zk_status TSRMLS_CC);
103+
return;
104+
}

php_zookeeper_exceptions.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) 2010 The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| http://www.php.net/license/3_01.txt. |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| license@php.net so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Authors: Ryan Uber <ru@ryanuber.com> |
14+
| Timandes White <timands@gmail.com> |
15+
+----------------------------------------------------------------------+
16+
*/
17+
18+
#ifndef PHP_ZOOKEEPER_EXCEPTIONS
19+
#define PHP_ZOOKEEPER_EXCEPTIONS
20+
21+
#include <Zend/zend_exceptions.h>
22+
23+
zend_class_entry *zk_base_exception;
24+
zend_class_entry *zk_optimeout_exception;
25+
zend_class_entry *zk_connection_exception;
26+
zend_class_entry *zk_marshalling_exception;
27+
zend_class_entry *zk_auth_exception;
28+
zend_class_entry *zk_session_exception;
29+
zend_class_entry *zk_nonode_exception;
30+
31+
/**
32+
* register exceptions
33+
*/
34+
void php_zk_register_exceptions(TSRMLS_D);
35+
zend_class_entry * php_zk_get_exception_with_message(zend_class_entry *ce, char *message TSRMLS_DC);
36+
/**
37+
* throw exception according to status
38+
*/
39+
void php_zk_throw_exception(int zk_status TSRMLS_DC);
40+
41+
#endif /* PHP_ZOOKEEPER_EXCEPTIONS */

tests/001.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Check for zookeeper presence
3+
--SKIPIF--
4+
<?php if (!extension_loaded("zookeeper")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
echo "zookeeper extension is available";
8+
?>
9+
--EXPECT--
10+
zookeeper extension is available

tests/check_if_exists_without_connect.phpt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ if (!extension_loaded('zookeeper')) {
88
--FILE--
99
<?php
1010
$client = new Zookeeper();
11-
$client->exists('/test1');
11+
try {
12+
$client->exists('/test1');
13+
} catch(ZookeeperConnectionException $zce) {
14+
printf("%s\n%d", $zce->getMessage(), $zce->getCode());
15+
}
1216
--EXPECTF--
13-
Warning: Zookeeper::exists(): Zookeeper connect was not called in %s on line %d
17+
Zookeeper->connect() was not called
18+
5998

tests/construct_retrieve_error_with_invalid_recv.phpt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ if (!extension_loaded('zookeeper')) {
77
};
88
--FILE--
99
<?php
10-
$client = new Zookeeper('localhost:2181', null, -1);
10+
try {
11+
$client = new Zookeeper('localhost:2181', null, -1);
12+
} catch (ZookeeperException $ze) {
13+
printf("%s\n%d", $ze->getMessage(), $ze->getCode());
14+
}
1115
--EXPECTF--
1216
Warning: Zookeeper::__construct(): recv_timeout parameter has to be greater than 0 in %s on line %d
17+
bad arguments
18+
-8

tests/create_node_retrieve_invalid_status_error.phpt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ if (!extension_loaded('zookeeper')) {
88
--FILE--
99
<?php
1010
$client = new Zookeeper('localhost:2181');
11-
$client->create('/test5', '', array());
11+
try {
12+
$client->create('/test5', '', array());
13+
} catch (ZookeeperException $ze) {
14+
printf("%s\n%d", $ze->getMessage(), $ze->getCode());
15+
}
1216
--EXPECTF--
13-
Warning: Zookeeper::create(): error: invalid acl in %s on line %d
17+
invalid acl
18+
-114

tests/create_node_without_connect.phpt

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ if (!extension_loaded('zookeeper')) {
88
--FILE--
99
<?php
1010
$client = new Zookeeper();
11-
12-
$client->create('/test6', null, array(
13-
array(
14-
'perms' => Zookeeper::PERM_ALL,
15-
'scheme' => 'world',
16-
'id' => 'anyone'
17-
)
18-
));
11+
try {
12+
$client->create('/test6', null, array(
13+
array(
14+
'perms' => Zookeeper::PERM_ALL,
15+
'scheme' => 'world',
16+
'id' => 'anyone'
17+
)
18+
));
19+
} catch(ZookeeperConnectionException $zce) {
20+
printf("%s\n%d", $zce->getMessage(), $zce->getCode());
21+
}
1922
--EXPECTF--
20-
Warning: Zookeeper::create(): Zookeeper connect was not called in %s on line %d
23+
Zookeeper->connect() was not called
24+
5998

0 commit comments

Comments
 (0)