Skip to content

Commit 2ffa3fb

Browse files
authored
Aggregate reported-errors up to 2kb (#42)
1 parent 942f6f7 commit 2ffa3fb

File tree

6 files changed

+79
-10
lines changed

6 files changed

+79
-10
lines changed

runtests

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash -ex
1+
#!/bin/bash -e
22

33
VALGRIND=0
44
REDIS_FOLDER=""

src/lib/parser.c

+19-5
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ _LIBRDB_API RdbParser *RDB_createParserRdb(RdbMemAlloc *memAlloc) {
207207
p->reader = NULL;
208208
p->cache = NULL;
209209
p->errorMsg[0] = '\0';
210+
p->errorMsgAt = 0;
210211
p->appCbCtx.numBulks = 0;
211212
p->loggerCb = loggerCbDefault;
212213
p->logLevel = RDB_LOG_DBG;
@@ -451,28 +452,41 @@ _LIBRDB_API RdbRes RDB_getErrorCode(RdbParser *p) {
451452
}
452453

453454
_LIBRDB_API void RDB_reportError(RdbParser *p, RdbRes e, const char *msg, ...) {
454-
int nchars = 0;
455-
p->errorCode = e;
455+
/* Record errorCode only of the first error */
456+
if (p->errorCode == RDB_OK)
457+
p->errorCode = e;
456458

457459
if (msg == NULL) {
458-
p->errorMsg[0] = '\0';
459460
return;
460461
}
461462

462463
/* RDB_OK & RDB_OK_DONT_PROPAGATE - not a real errors to report */
463464
assert (e != RDB_OK && e != RDB_OK_DONT_PROPAGATE);
464465

466+
/* If error message is too long, then trim it in order to record this last message */
467+
if (p->errorMsgAt > LAST_ERR_MSG_OFFSET) {
468+
p->errorMsgAt = LAST_ERR_MSG_OFFSET;
469+
p->errorMsgAt += snprintf(p->errorMsg + p->errorMsgAt,
470+
MAX_ERROR_MSG - p->errorMsgAt,
471+
"\n... last recorded error message: ...\n");
472+
}
473+
p->errorMsgAt += snprintf(p->errorMsg + p->errorMsgAt, MAX_ERROR_MSG - p->errorMsgAt, "[errcode=%d] ", e);
474+
465475
if (p->state == RDB_STATE_RUNNING) {
466-
nchars = snprintf(p->errorMsg, MAX_ERROR_MSG, "[%s::State=%d] ",
476+
p->errorMsgAt += snprintf(p->errorMsg + p->errorMsgAt,
477+
MAX_ERROR_MSG - p->errorMsgAt, "[%s::State=%d] ",
467478
peInfo[p->parsingElement].funcname,
468479
p->elmCtx.state);
469480
}
470481

471482
va_list args;
472483
va_start(args, msg);
473-
vsnprintf(p->errorMsg + nchars, MAX_ERROR_MSG - nchars, msg, args);
484+
p->errorMsgAt += vsnprintf(p->errorMsg + p->errorMsgAt, MAX_ERROR_MSG - p->errorMsgAt, msg, args);
474485
va_end(args);
475486

487+
if (p->errorMsgAt >= MAX_ERROR_MSG) return;
488+
p->errorMsgAt += snprintf(p->errorMsg + p->errorMsgAt, MAX_ERROR_MSG - p->errorMsgAt, "\n");
489+
476490
RDB_log(p, RDB_LOG_ERR, "%s", p->errorMsg);
477491
}
478492

src/lib/parser.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
#include "defines.h"
77
#include "../../api/librdb-api.h"
88

9-
#define MAX_ERROR_MSG 1024
9+
10+
/* Max error message length. Chain one or more recorded error messages. */
11+
#define MAX_ERROR_MSG 2048
12+
/* When reaching configured offset, keep overwrite the last error message */
13+
#define LAST_ERR_MSG_OFFSET 1600
14+
1015
#define MAX_APP_BULKS 2
1116
#define NOP /*no-op*/
1217
#define IF_NOT_OK_RETURN(cmd) do {RdbStatus s; s = cmd; if (unlikely(s!=RDB_STATUS_OK)) return s;} while (0)
@@ -372,7 +377,9 @@ struct RdbParser {
372377

373378
/*** error reporting ***/
374379
RdbRes errorCode;
380+
375381
char errorMsg[MAX_ERROR_MSG];
382+
int errorMsgAt;
376383

377384
/*** read RDB from reader VS read RDB from buffer ***/
378385

test/test_common.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ void cleanTmpFolder(void) {
105105
const char *folder_path = "./test/tmp";
106106

107107
DIR *dir = opendir(folder_path);
108-
assert_true(dir != NULL);
108+
if (dir == NULL) {
109+
printf("Failed to open directory: %s\n", folder_path);
110+
assert_true(0);
111+
}
109112

110113
struct dirent *entry;
111114
while ((entry = readdir(dir)) != NULL) {

test/test_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,6 @@ void setEnvVar (const char *name, const char *val);
7676
char *substring(char *str, size_t len, char *substr);
7777
void assert_file_payload(const char *filename, char *expData, int expLen, MatchType matchType, int expMatch);
7878

79+
void dummyLogger(RdbLogLevel l, const char *msg);
80+
7981
int printHexDump(const char *addr, size_t len, char *obuf, int obuflen);

test/test_main.c

+45-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ static void test_createReader_missingFile(void **state) {
1818
assert_int_equal(err, RDB_ERR_FAILED_OPEN_RDB_FILE);
1919

2020
/* verify returned error string */
21-
assert_string_equal(RDB_getErrorMessage(parser),
22-
"Failed to open RDB file `./test/dumps/non_exist_file.rdb`: No such file or directory\n");
21+
assert_true(strstr(RDB_getErrorMessage(parser), "Failed to open RDB file"));
2322
RDB_deleteParser(parser);
2423
}
2524

@@ -110,6 +109,49 @@ static void test_examples(void **state) {
110109
runSystemCmd("make example > /dev/null ");
111110
}
112111

112+
RdbRes handle_start_rdb_report_long_errors(RdbParser *p, void *userData, int rdbVersion) {
113+
UNUSED(userData, rdbVersion);
114+
for (int i = 2 ; i < 1000; i++)
115+
RDB_reportError(p, (RdbRes) i, "Error Report number:%d", i);
116+
return 1001; /* This value will be eventually returned as the error code */
117+
}
118+
119+
static void test_report_long_error(void **state) {
120+
RdbStatus status;
121+
UNUSED(state);
122+
void *user_data = NULL;
123+
124+
RdbHandlersRawCallbacks cb = { .handleStartRdb = handle_start_rdb_report_long_errors };
125+
RdbParser *parser = RDB_createParserRdb(NULL);
126+
RDB_setLogger(parser, dummyLogger);
127+
assert_non_null(RDBX_createReaderFile(parser, "./test/dumps/quicklist2_v11.rdb"));
128+
assert_non_null(RDB_createHandlersRaw(parser, &cb, user_data, NULL));
129+
130+
131+
while ((status = RDB_parse(parser)) == RDB_STATUS_WAIT_MORE_DATA);
132+
assert_int_equal(status, RDB_STATUS_ERROR);
133+
const char *returned = RDB_getErrorMessage(parser);
134+
const char *expected =
135+
"[errcode=2] [elementRdbHeader::State=0] Error Report number:2\n"
136+
"[errcode=3] [elementRdbHeader::State=0] Error Report number:3\n[errcode=4] [elementRdbHeader::State=0] Error Report number:4\n"
137+
"[errcode=5] [elementRdbHeader::State=0] Error Report number:5\n[errcode=6] [elementRdbHeader::State=0] Error Report number:6\n"
138+
"[errcode=7] [elementRdbHeader::State=0] Error Report number:7\n[errcode=8] [elementRdbHeader::State=0] Error Report number:8\n"
139+
"[errcode=9] [elementRdbHeader::State=0] Error Report number:9\n[errcode=10] [elementRdbHeader::State=0] Error Report number:10\n"
140+
"[errcode=11] [elementRdbHeader::State=0] Error Report number:11\n[errcode=12] [elementRdbHeader::State=0] Error Report number:12\n"
141+
"[errcode=13] [elementRdbHeader::State=0] Error Report number:13\n[errcode=14] [elementRdbHeader::State=0] Error Report number:14\n"
142+
"[errcode=15] [elementRdbHeader::State=0] Error Report number:15\n[errcode=16] [elementRdbHeader::State=0] Error Report number:16\n"
143+
"[errcode=17] [elementRdbHeader::State=0] Error Report number:17\n[errcode=18] [elementRdbHeader::State=0] Error Report number:18\n"
144+
"[errcode=19] [elementRdbHeader::State=0] Error Report number:19\n[errcode=20] [elementRdbHeader::State=0] Error Report number:20\n"
145+
"[errcode=21] [elementRdbHeader::State=0] Error Report number:21\n[errcode=22] [elementRdbHeader::State=0] Error Report number:22\n"
146+
"[errcode=23] [elementRdbHeader::State=0] Error Report number:23\n[errcode=24] [elementRdbHeader::State=0] Error Report number:24\n"
147+
"[errcode=25] [elementRdbHeader::State=0] Error Report number:25\n[errcode=26] [elementRdbHeader::State=0] Error Report number:26\n"
148+
"[errcode=27] [el\n... last recorded error message: ...\n[errcode=999] [elementRdbHeader::State=0] Error Report number:999\n";
149+
150+
assert_string_equal(returned, expected);
151+
assert_int_equal(RDB_getErrorCode(parser), 1001);
152+
RDB_deleteParser(parser);
153+
}
154+
113155
static void printResPicture(int result) {
114156
if (result)
115157
printf(" x_x\n"
@@ -153,6 +195,7 @@ int group_misc(void) {
153195
cmocka_unit_test(test_empty_rdb),
154196
cmocka_unit_test(test_mixed_levels_registration),
155197
cmocka_unit_test(test_checksum),
198+
cmocka_unit_test(test_report_long_error),
156199
};
157200
return cmocka_run_group_tests(tests, NULL, NULL);
158201
}

0 commit comments

Comments
 (0)