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",
|
||||
__FILE__, __LINE__);
|
||||
} else {
|
||||
PyErr_Format(PylibMCExc_MemcachedError, "error %d from %s: %s",
|
||||
error, what, memcached_strerror(self->mc, error));
|
||||
PylibMC_McErr *err;
|
||||
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;
|
||||
}
|
||||
@ -976,6 +986,7 @@ static PyMethodDef PylibMC_functions[] = {
|
||||
PyMODINIT_FUNC init_pylibmc(void) {
|
||||
PyObject *module;
|
||||
PylibMC_Behavior *b;
|
||||
PylibMC_McErr *err;
|
||||
char name[128];
|
||||
|
||||
if (PyType_Ready(&PylibMC_ClientType) < 0) {
|
||||
@ -1006,12 +1017,20 @@ Oh, and: plankton.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PyModule_AddStringConstant(module, "__version__", PYLIBMC_VERSION);
|
||||
|
||||
PylibMCExc_MemcachedError = PyErr_NewException(
|
||||
"_pylibmc.MemcachedError", NULL, NULL);
|
||||
PyModule_AddObject(module, "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);
|
||||
PyModule_AddObject(module, "client", (PyObject *)&PylibMC_ClientType);
|
||||
|
@ -68,6 +68,53 @@ typedef memcached_return (*_PylibMC_SetCommand)(memcached_st *, const char *,
|
||||
|
||||
/* {{{ Exceptions */
|
||||
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 */
|
||||
|
10
tests.py
10
tests.py
@ -147,6 +147,16 @@ True
|
||||
True
|
||||
>>> 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.
|
||||
>>> c.set_behaviors({"tcp_nodelay": True, "hash": 6})
|
||||
>>> list(sorted((k, v) for (k, v) in c.get_behaviors().items()
|
||||
|
Reference in New Issue
Block a user