summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--async.c6
-rw-r--r--async.h5
-rw-r--r--example.c4
-rw-r--r--hiredis.c37
-rw-r--r--hiredis.h12
-rw-r--r--test.c11
6 files changed, 47 insertions, 28 deletions
diff --git a/async.c b/async.c
index d6a33f9..424c2b2 100644
--- a/async.c
+++ b/async.c
@@ -47,8 +47,8 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
* an indirection to the redisContext struct. */
static void __redisAsyncCopyError(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
- if (c->error != NULL)
- ac->error = c->error;
+ ac->err = c->err;
+ ac->errstr = c->errstr;
}
redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
@@ -128,7 +128,7 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) {
/* Make sure error is accessible if there is any */
__redisAsyncCopyError(ac);
- status = (ac->error == NULL) ? REDIS_OK : REDIS_ERR;
+ status = (ac->err == 0) ? REDIS_OK : REDIS_ERR;
if (status == REDIS_OK) {
/* When the connection is cleanly disconnected, there should not
diff --git a/async.h b/async.h
index 2e14b13..d0a99da 100644
--- a/async.h
+++ b/async.h
@@ -54,8 +54,9 @@ typedef struct redisAsyncContext {
/* Hold the regular context, so it can be realloc'ed. */
redisContext c;
- /* Hold a reference to the error object so it can be used directly. */
- char *error;
+ /* Setup error flags so they can be used directly. */
+ int err;
+ char *errstr;
/* Called when the library expects to start reading/writing.
* The supplied functions should be idempotent. */
diff --git a/example.c b/example.c
index d784e33..676814a 100644
--- a/example.c
+++ b/example.c
@@ -10,8 +10,8 @@ int main(void) {
redisReply *reply;
c = redisConnect((char*)"127.0.0.1", 6379);
- if (c->error != NULL) {
- printf("Connection error: %s\n", c->error);
+ if (c->err) {
+ printf("Connection error: %s\n", c->errstr);
exit(1);
}
diff --git a/hiredis.c b/hiredis.c
index 8848def..0aabd25 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -614,6 +614,17 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz
return totlen;
}
+static void __redisSetError(redisContext *c, int type, const char *str) {
+ c->err = type;
+ if (str) {
+ c->errstr = sdsnew(str);
+ } else {
+ /* Only REDIS_ERR_IO may lack a description! */
+ assert(type == REDIS_ERR_IO);
+ c->errstr = sdsnew(strerror(errno));
+ }
+}
+
static int redisContextConnect(redisContext *c, const char *ip, int port) {
char err[ANET_ERR_LEN];
if (c->flags & REDIS_BLOCK) {
@@ -623,11 +634,11 @@ static int redisContextConnect(redisContext *c, const char *ip, int port) {
}
if (c->fd == ANET_ERR) {
- c->error = sdsnew(err);
+ __redisSetError(c,REDIS_ERR_CONN,err);
return REDIS_ERR;
}
if (anetTcpNoDelay(err,c->fd) == ANET_ERR) {
- c->error = sdsnew(err);
+ __redisSetError(c,REDIS_ERR_CONN,err);
return REDIS_ERR;
}
return REDIS_OK;
@@ -635,7 +646,8 @@ static int redisContextConnect(redisContext *c, const char *ip, int port) {
static redisContext *redisContextInit() {
redisContext *c = calloc(sizeof(redisContext),1);
- c->error = NULL;
+ c->err = 0;
+ c->errstr = NULL;
c->obuf = sdsempty();
c->fn = &defaultFunctions;
c->reader = NULL;
@@ -646,8 +658,8 @@ void redisFree(redisContext *c) {
/* Disconnect before free'ing if not yet disconnected. */
if (c->flags & REDIS_CONNECTED)
close(c->fd);
- if (c->error != NULL)
- sdsfree(c->error);
+ if (c->errstr != NULL)
+ sdsfree(c->errstr);
if (c->obuf != NULL)
sdsfree(c->obuf);
if (c->reader != NULL)
@@ -702,14 +714,12 @@ int redisBufferRead(redisContext *c) {
if (errno == EAGAIN) {
/* Try again later */
} else {
- /* Set error in context */
- c->error = sdscatprintf(sdsempty(),
- "read: %s", strerror(errno));
+ __redisSetError(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
} else if (nread == 0) {
- c->error = sdscatprintf(sdsempty(),
- "read: Server closed the connection");
+ __redisSetError(c,REDIS_ERR_EOF,
+ "Server closed the connection");
return REDIS_ERR;
} else {
__redisCreateReplyReader(c);
@@ -735,9 +745,7 @@ int redisBufferWrite(redisContext *c, int *done) {
if (errno == EAGAIN) {
/* Try again later */
} else {
- /* Set error in context */
- c->error = sdscatprintf(sdsempty(),
- "write: %s", strerror(errno));
+ __redisSetError(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
} else if (nwritten > 0) {
@@ -758,8 +766,7 @@ int redisBufferWrite(redisContext *c, int *done) {
static int __redisGetReply(redisContext *c, void **reply) {
__redisCreateReplyReader(c);
if (redisReplyReaderGetReply(c->reader,reply) == REDIS_ERR) {
- /* Copy the (protocol) error from the reader to the context. */
- c->error = sdsnew(((redisReader*)c->reader)->error);
+ __redisSetError(c,REDIS_ERR_PROTOCOL,((redisReader*)c->reader)->error);
return REDIS_ERR;
}
return REDIS_OK;
diff --git a/hiredis.h b/hiredis.h
index a68720e..76d7264 100644
--- a/hiredis.h
+++ b/hiredis.h
@@ -35,6 +35,15 @@
#define REDIS_ERR -1
#define REDIS_OK 0
+/* When an error occurs, the err flag in a context is set to hold the type of
+ * error that occured. REDIS_ERR_IO means there was an I/O error and you
+ * should use the "errno" variable to find out what is wrong.
+ * For other values, the "errstr" field will hold a description. */
+#define REDIS_ERR_IO 1 /* error in read or write */
+#define REDIS_ERR_CONN 2 /* error connecting */
+#define REDIS_ERR_EOF 3 /* eof */
+#define REDIS_ERR_PROTOCOL 4 /* protocol error */
+
/* Connection type can be blocking or non-blocking and is set in the
* least significant bit of the flags field in redisContext. */
#define REDIS_BLOCK 0x1
@@ -87,8 +96,9 @@ struct redisContext; /* need forward declaration of redisContext */
typedef struct redisContext {
int fd;
int flags;
- char *error; /* Error object is set when in erronous state */
char *obuf; /* Write buffer */
+ int err; /* Error flags, 0 when there is no error */
+ char *errstr; /* String representation of error when applicable */
/* Function set for reply buildup and reply reader */
redisReplyObjectFunctions *fn;
diff --git a/test.c b/test.c
index b6e86f5..11e762b 100644
--- a/test.c
+++ b/test.c
@@ -22,8 +22,8 @@ static long long usec(void) {
static redisContext *blocking_context = NULL;
static void __connect(redisContext **target) {
*target = blocking_context = redisConnect((char*)"127.0.0.1", 6379);
- if (blocking_context->error != NULL) {
- printf("Connection error: %s\n", blocking_context->error);
+ if (blocking_context->err) {
+ printf("Connection error: %s\n", blocking_context->errstr);
exit(1);
}
}
@@ -77,9 +77,10 @@ static void test_blocking_connection() {
__connect(&c);
test("Returns I/O error when the connection is lost: ");
reply = redisCommand(c,"QUIT");
- test_cond(redisCommand(c,"PING") == NULL &&
- strcasecmp(reply->str,"OK") == 0 &&
- strcmp(c->error,"read: Server closed the connection") == 0);
+ test_cond(strcasecmp(reply->str,"OK") == 0 &&
+ redisCommand(c,"PING") == NULL &&
+ c->err == REDIS_ERR_EOF &&
+ strcmp(c->errstr,"Server closed the connection") == 0);
freeReplyObject(reply);
redisFree(c);