diff --git a/src/networking.cpp b/src/networking.cpp index f1ec92bbe..dc4e56e92 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -494,7 +494,7 @@ void addReplyErrorLength(client *c, const char *s, size_t len) { } /* Do some actions after an error reply was sent (Log if needed, updates stats, etc.) */ -void afterErrorReply(client *c, const char *s, size_t len) { +void afterErrorReply(client *c, const char *s, size_t len, int severity = ERR_CRITICAL) { /* Sometimes it could be normal that a replica replies to a master with * an error and this function gets called. Actually the error will never * be sent because addReply*() against master clients has no effect... @@ -522,9 +522,30 @@ void afterErrorReply(client *c, const char *s, size_t len) { if (len > 4096) len = 4096; const char *cmdname = c->lastcmd ? c->lastcmd->name : ""; - serverLog(LL_WARNING,"== CRITICAL == This %s is sending an error " - "to its %s: '%.*s' after processing the command " - "'%s'", from, to, (int)len, s, cmdname); + switch (severity) { + case ERR_NOTICE: + serverLog(LL_NOTICE,"== NOTICE == This %s is rejecting a command " + "from its %s: '%.*s' after processing the command " + "'%s'", from, to, (int)len, s, cmdname); + break; + case ERR_WARNING: + serverLog(LL_WARNING,"== WARNING == This %s is rejecting a command " + "from its %s: '%.*s' after processing the command " + "'%s'", from, to, (int)len, s, cmdname); + break; + case ERR_ERROR: + serverLog(LL_WARNING,"== ERROR == This %s is sending an error " + "to its %s: '%.*s' after processing the command " + "'%s'", from, to, (int)len, s, cmdname); + break; + case ERR_CRITICAL: + default: + serverLog(LL_WARNING,"== CRITICAL == This %s is sending an error " + "to its %s: '%.*s' after processing the command " + "'%s'", from, to, (int)len, s, cmdname); + break; + } + if (ctype == CLIENT_TYPE_MASTER && g_pserver->repl_backlog && g_pserver->repl_backlog_histlen > 0) { @@ -536,9 +557,9 @@ void afterErrorReply(client *c, const char *s, size_t len) { /* The 'err' object is expected to start with -ERRORCODE and end with \r\n. * Unlike addReplyErrorSds and others alike which rely on addReplyErrorLength. */ -void addReplyErrorObject(client *c, robj *err) { +void addReplyErrorObject(client *c, robj *err, int severity) { addReply(c, err); - afterErrorReply(c, szFromObj(err), sdslen(szFromObj(err))-2); /* Ignore trailing \r\n */ + afterErrorReply(c, szFromObj(err), sdslen(szFromObj(err))-2, severity); /* Ignore trailing \r\n */ } void addReplyError(client *c, const char *err) { diff --git a/src/server.cpp b/src/server.cpp index 624612f89..0b0fdc877 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3773,13 +3773,14 @@ void call(client *c, int flags) { * If there's a transaction is flags it as dirty, and if the command is EXEC, * it aborts the transaction. * Note: 'reply' is expected to end with \r\n */ -void rejectCommand(client *c, robj *reply) { +void rejectCommand(client *c, robj *reply, int severity = ERR_CRITICAL) { flagTransaction(c); if (c->cmd && c->cmd->proc == execCommand) { execCommandAbort(c, szFromObj(reply)); - } else { + } + else { /* using addReplyError* rather than addReply so that the error can be logged. */ - addReplyErrorObject(c, reply); + addReplyErrorObject(c, reply, severity); } } @@ -4024,7 +4025,7 @@ int processCommand(client *c, int callFlags) { /* Active Replicas can execute read only commands, and optionally write commands */ if (!(g_pserver->loading == LOADING_REPLICATION && g_pserver->fActiveReplica && ((c->cmd->flags & CMD_READONLY) || g_pserver->fWriteDuringActiveLoad))) { - rejectCommand(c, shared.loadingerr); + rejectCommand(c, shared.loadingerr, ERR_WARNING); return C_OK; } } diff --git a/src/server.h b/src/server.h index c6b9a77b5..0da8b84f3 100644 --- a/src/server.h +++ b/src/server.h @@ -543,6 +543,12 @@ extern int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT]; #define LL_WARNING 3 #define LL_RAW (1<<10) /* Modifier to log without timestamp */ +/* Error severity levels */ +#define ERR_CRITICAL 0 +#define ERR_ERROR 1 +#define ERR_WARNING 2 +#define ERR_NOTICE 3 + /* Supervision options */ #define SUPERVISED_NONE 0 #define SUPERVISED_AUTODETECT 1 @@ -2056,7 +2062,7 @@ void addReplyBulkLongLong(client *c, long long ll); void addReply(client *c, robj_roptr obj); void addReplySds(client *c, sds s); void addReplyBulkSds(client *c, sds s); -void addReplyErrorObject(client *c, robj *err); +void addReplyErrorObject(client *c, robj *err, int severity); void addReplyErrorSds(client *c, sds err); void addReplyError(client *c, const char *err); void addReplyStatus(client *c, const char *status);