From 5610952da2f4190573bc10467fcf249a9e7eff4b Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Thu, 28 Nov 2013 18:28:26 +0100 Subject: [PATCH] frontend: Unified error reporting to the client. Keep track of the latest error in a connection object and report that back to the client in case a command handler failed. --- src/frontend/connection.c | 21 +++++++++++++++++---- src/frontend/query.c | 5 ++--- src/include/frontend/connection-private.h | 2 ++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 21bca4f..962cd9c 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -65,6 +65,12 @@ connection_init(sdb_object_t *obj, va_list ap) "for a new connection"); return -1; } + conn->errbuf = sdb_strbuf_create(0); + if (! conn->errbuf) { + sdb_log(SDB_LOG_ERR, "frontend: Failed to allocate an error buffer " + "for a new connection"); + return -1; + } conn->client_addr_len = sizeof(conn->client_addr); conn->fd = accept(sock_fd, (struct sockaddr *)&conn->client_addr, @@ -128,6 +134,8 @@ connection_destroy(sdb_object_t *obj) sdb_strbuf_destroy(conn->buf); conn->buf = NULL; + sdb_strbuf_destroy(conn->errbuf); + conn->errbuf = NULL; } /* connection_destroy */ static sdb_type_t connection_type = { @@ -164,6 +172,9 @@ command_handle(sdb_conn_t *conn) sdb_log(SDB_LOG_DEBUG, "frontend: Handling command %u (len: %u)", conn->cmd, conn->cmd_len); + /* reset */ + sdb_strbuf_sprintf(conn->errbuf, ""); + switch (conn->cmd) { case CONNECTION_PING: status = sdb_connection_ping(conn); @@ -178,16 +189,18 @@ command_handle(sdb_conn_t *conn) default: { - char errbuf[1024]; sdb_log(SDB_LOG_WARNING, "frontend: Ignoring invalid command"); - snprintf(errbuf, sizeof(errbuf), "Invalid command %#x", conn->cmd); - sdb_connection_send(conn, CONNECTION_ERROR, - (uint32_t)(strlen(errbuf) + 1), errbuf); + sdb_strbuf_sprintf(conn->errbuf, "Invalid command %#x", conn->cmd); status = -1; break; } } + if (status) + sdb_connection_send(conn, CONNECTION_ERROR, + (uint32_t)sdb_strbuf_len(conn->errbuf), + sdb_strbuf_string(conn->errbuf)); + /* remove the command from the buffer */ if (conn->cmd_len) sdb_strbuf_skip(conn->buf, conn->cmd_len); diff --git a/src/frontend/query.c b/src/frontend/query.c index 9e3b66a..fa493a6 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -50,8 +50,7 @@ sdb_fe_list(sdb_conn_t *conn) "buffer to handle LIST command: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); - /* XXX: send error message */ - sdb_connection_send(conn, CONNECTION_ERROR, 0, NULL); + sdb_strbuf_sprintf(conn->errbuf, "Out of memory"); sdb_strbuf_destroy(buf); return -1; } @@ -59,7 +58,7 @@ sdb_fe_list(sdb_conn_t *conn) if (sdb_store_tojson(buf)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "store to JSON"); - sdb_connection_send(conn, CONNECTION_ERROR, 0, NULL); + sdb_strbuf_sprintf(conn->errbuf, "Out of memory"); sdb_strbuf_destroy(buf); return -1; } diff --git a/src/include/frontend/connection-private.h b/src/include/frontend/connection-private.h index d484a08..6cf7395 100644 --- a/src/include/frontend/connection-private.h +++ b/src/include/frontend/connection-private.h @@ -60,6 +60,8 @@ struct sdb_conn { uint32_t cmd; uint32_t cmd_len; + sdb_strbuf_t *errbuf; + /* user information */ char *username; /* NULL if the user has not been authenticated */ }; -- 2.30.2