Add specialized exception classes.
Useful when you need to catch certain errors like when a key isn't found during an increment/decrement operation.
This commit is contained in:
parent
529adbe6bb
commit
1c83ad0de2
@ -890,8 +890,18 @@ static PyObject *PylibMC_ErrFromMemcached(PylibMC_Client *self, const char *what
|
|||||||
PyErr_Format(PyExc_RuntimeError, "error == 0? %s:%d",
|
PyErr_Format(PyExc_RuntimeError, "error == 0? %s:%d",
|
||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
} else {
|
} else {
|
||||||
PyErr_Format(PylibMCExc_MemcachedError, "error %d from %s: %s",
|
PylibMC_McErr *err;
|
||||||
error, what, memcached_strerror(self->mc, error));
|
PyObject *exc = (PyObject *)PylibMCExc_MemcachedError;
|
||||||
|
|
||||||
|
for (err = PylibMCExc_mc_errs; err->name != NULL; err++) {
|
||||||
|
if (err->rc == error) {
|
||||||
|
exc = err->exc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_Format(exc, "error %d from %s: %s", error, what,
|
||||||
|
memcached_strerror(self->mc, error));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -976,6 +986,7 @@ static PyMethodDef PylibMC_functions[] = {
|
|||||||
PyMODINIT_FUNC init_pylibmc(void) {
|
PyMODINIT_FUNC init_pylibmc(void) {
|
||||||
PyObject *module;
|
PyObject *module;
|
||||||
PylibMC_Behavior *b;
|
PylibMC_Behavior *b;
|
||||||
|
PylibMC_McErr *err;
|
||||||
char name[128];
|
char name[128];
|
||||||
|
|
||||||
if (PyType_Ready(&PylibMC_ClientType) < 0) {
|
if (PyType_Ready(&PylibMC_ClientType) < 0) {
|
||||||
@ -1006,12 +1017,20 @@ Oh, and: plankton.\n");
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyModule_AddStringConstant(module, "__version__", PYLIBMC_VERSION);
|
||||||
|
|
||||||
PylibMCExc_MemcachedError = PyErr_NewException(
|
PylibMCExc_MemcachedError = PyErr_NewException(
|
||||||
"_pylibmc.MemcachedError", NULL, NULL);
|
"_pylibmc.MemcachedError", NULL, NULL);
|
||||||
PyModule_AddObject(module, "MemcachedError",
|
PyModule_AddObject(module, "MemcachedError",
|
||||||
(PyObject *)PylibMCExc_MemcachedError);
|
(PyObject *)PylibMCExc_MemcachedError);
|
||||||
|
|
||||||
PyModule_AddStringConstant(module, "__version__", PYLIBMC_VERSION);
|
for (err = PylibMCExc_mc_errs; err->name != NULL; err++) {
|
||||||
|
char excnam[64];
|
||||||
|
strncpy(excnam, "_pylibmc.", 64);
|
||||||
|
strncat(excnam, err->name, 64);
|
||||||
|
err->exc = PyErr_NewException(excnam, PylibMCExc_MemcachedError, NULL);
|
||||||
|
PyModule_AddObject(module, err->name, (PyObject *)err->exc);
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(&PylibMC_ClientType);
|
Py_INCREF(&PylibMC_ClientType);
|
||||||
PyModule_AddObject(module, "client", (PyObject *)&PylibMC_ClientType);
|
PyModule_AddObject(module, "client", (PyObject *)&PylibMC_ClientType);
|
||||||
|
@ -68,6 +68,53 @@ typedef memcached_return (*_PylibMC_SetCommand)(memcached_st *, const char *,
|
|||||||
|
|
||||||
/* {{{ Exceptions */
|
/* {{{ Exceptions */
|
||||||
static PyObject *PylibMCExc_MemcachedError;
|
static PyObject *PylibMCExc_MemcachedError;
|
||||||
|
|
||||||
|
/* Mapping of memcached_return value -> Python exception object. */
|
||||||
|
typedef struct {
|
||||||
|
memcached_return rc;
|
||||||
|
char *name;
|
||||||
|
PyObject *exc;
|
||||||
|
} PylibMC_McErr;
|
||||||
|
|
||||||
|
static PylibMC_McErr PylibMCExc_mc_errs[] = {
|
||||||
|
{ MEMCACHED_FAILURE, "Failure", NULL },
|
||||||
|
{ MEMCACHED_HOST_LOOKUP_FAILURE, "HostLookupError", NULL },
|
||||||
|
{ MEMCACHED_CONNECTION_FAILURE, "ConnectionError", NULL },
|
||||||
|
{ MEMCACHED_CONNECTION_BIND_FAILURE, "ConnectionBindError", NULL },
|
||||||
|
{ MEMCACHED_WRITE_FAILURE, "WriteError", NULL },
|
||||||
|
{ MEMCACHED_READ_FAILURE, "ReadError", NULL },
|
||||||
|
{ MEMCACHED_UNKNOWN_READ_FAILURE, "UnknownReadFailure", NULL },
|
||||||
|
{ MEMCACHED_PROTOCOL_ERROR, "ProtocolError", NULL },
|
||||||
|
{ MEMCACHED_CLIENT_ERROR, "ClientError", NULL },
|
||||||
|
{ MEMCACHED_SERVER_ERROR, "ServerError", NULL },
|
||||||
|
{ MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE, "SocketCreateError", NULL },
|
||||||
|
{ MEMCACHED_DATA_EXISTS, "DataExists", NULL },
|
||||||
|
{ MEMCACHED_DATA_DOES_NOT_EXIST, "DataDoesNotExist", NULL },
|
||||||
|
//{ MEMCACHED_NOTSTORED, "NotStored", NULL },
|
||||||
|
//{ MEMCACHED_STORED, "Stored", NULL },
|
||||||
|
{ MEMCACHED_NOTFOUND, "NotFound", NULL },
|
||||||
|
{ MEMCACHED_MEMORY_ALLOCATION_FAILURE, "AllocationError", NULL },
|
||||||
|
//{ MEMCACHED_PARTIAL_READ, "PartialRead", NULL },
|
||||||
|
{ MEMCACHED_SOME_ERRORS, "SomeErrors", NULL },
|
||||||
|
{ MEMCACHED_NO_SERVERS, "NoServers", NULL },
|
||||||
|
//{ MEMCACHED_END, "", NULL },
|
||||||
|
//{ MEMCACHED_DELETED, "", NULL },
|
||||||
|
//{ MEMCACHED_VALUE, "", NULL },
|
||||||
|
//{ MEMCACHED_STAT, "", NULL },
|
||||||
|
//{ MEMCACHED_ITEM, "", NULL },
|
||||||
|
//{ MEMCACHED_ERRNO, "", NULL },
|
||||||
|
{ MEMCACHED_FAIL_UNIX_SOCKET, "UnixSocketError", NULL },
|
||||||
|
{ MEMCACHED_NOT_SUPPORTED, "NotSupportedError", NULL },
|
||||||
|
{ MEMCACHED_FETCH_NOTFINISHED, "FetchNotFinished", NULL },
|
||||||
|
//{ MEMCACHED_TIMEOUT, "TimeoutError", NULL },
|
||||||
|
//{ MEMCACHED_BUFFERED, "Buffer, NULL },
|
||||||
|
{ MEMCACHED_BAD_KEY_PROVIDED, "BadKeyProvided", NULL },
|
||||||
|
{ MEMCACHED_INVALID_HOST_PROTOCOL, "InvalidHostProtocolError", NULL },
|
||||||
|
//{ MEMCACHED_SERVER_MARKED_DEAD,
|
||||||
|
{ MEMCACHED_UNKNOWN_STAT_KEY, "UnknownStatKey", NULL },
|
||||||
|
{ MEMCACHED_E2BIG, "TooBigError", NULL },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Behavior statics */
|
/* {{{ Behavior statics */
|
||||||
|
10
tests.py
10
tests.py
@ -147,6 +147,16 @@ True
|
|||||||
True
|
True
|
||||||
>>> del c2
|
>>> del c2
|
||||||
|
|
||||||
|
Per-error exceptions
|
||||||
|
>>> c.incr("test")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
NotFound: error 16 from memcached_increment: NOT FOUND
|
||||||
|
>>> c.incr(chr(0))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ProtocolError: error 8 from memcached_increment: PROTOCOL ERROR
|
||||||
|
|
||||||
Behaviors.
|
Behaviors.
|
||||||
>>> c.set_behaviors({"tcp_nodelay": True, "hash": 6})
|
>>> c.set_behaviors({"tcp_nodelay": True, "hash": 6})
|
||||||
>>> list(sorted((k, v) for (k, v) in c.get_behaviors().items()
|
>>> list(sorted((k, v) for (k, v) in c.get_behaviors().items()
|
||||||
|
Reference in New Issue
Block a user