Improve maxavro failure handling and error messages
When the creation of the Avro schema would fail for a file that is being opened, the errors wouldn't be handled properly. Also free all allocated memory on failure. All errors that set errno are now properly logged with the error number and message.
This commit is contained in:
parent
84040be182
commit
8da655b7cb
@ -16,10 +16,31 @@
|
||||
#include <string.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
|
||||
static bool maxavro_read_sync(FILE *file, uint8_t* sync)
|
||||
{
|
||||
return fread(sync, 1, SYNC_MARKER_SIZE, file) == SYNC_MARKER_SIZE;
|
||||
bool rval = true;
|
||||
|
||||
if (fread(sync, 1, SYNC_MARKER_SIZE, file) != SYNC_MARKER_SIZE)
|
||||
{
|
||||
rval = false;
|
||||
|
||||
if (ferror(file))
|
||||
{
|
||||
char err[STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to read file sync marker: %d, %s", errno,
|
||||
strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else if (feof(file))
|
||||
{
|
||||
MXS_ERROR("Short read when reading file sync marker.");
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Unspecified error when reading file sync marker.");
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool maxavro_verify_block(MAXAVRO_FILE *file)
|
||||
@ -72,12 +93,24 @@ bool maxavro_read_datablock_start(MAXAVRO_FILE* file)
|
||||
|
||||
if (rval)
|
||||
{
|
||||
file->block_size = bytes;
|
||||
file->records_in_block = records;
|
||||
file->records_read_from_block = 0;
|
||||
file->data_start_pos = ftell(file->file);
|
||||
ss_dassert(file->data_start_pos > file->block_start_pos);
|
||||
file->metadata_read = true;
|
||||
long pos = ftell(file->file);
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
rval = false;
|
||||
char err[STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to read datablock start: %d, %s", errno,
|
||||
strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else
|
||||
{
|
||||
file->block_size = bytes;
|
||||
file->records_in_block = records;
|
||||
file->records_read_from_block = 0;
|
||||
file->data_start_pos = pos;
|
||||
ss_dassert(file->data_start_pos > file->block_start_pos);
|
||||
file->metadata_read = true;
|
||||
}
|
||||
}
|
||||
else if (maxavro_get_error(file) != MAXAVRO_ERR_NONE)
|
||||
{
|
||||
@ -153,35 +186,47 @@ MAXAVRO_FILE* maxavro_file_open(const char* filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MAXAVRO_FILE* avrofile = calloc(1, sizeof(MAXAVRO_FILE));
|
||||
bool error = false;
|
||||
|
||||
if (avrofile)
|
||||
MAXAVRO_FILE* avrofile = calloc(1, sizeof(MAXAVRO_FILE));
|
||||
char *my_filename = strdup(filename);
|
||||
char *schema = read_schema(avrofile);
|
||||
|
||||
if (avrofile && my_filename && schema)
|
||||
{
|
||||
avrofile->file = file;
|
||||
avrofile->filename = strdup(filename);
|
||||
char *schema = read_schema(avrofile);
|
||||
avrofile->schema = schema ? maxavro_schema_alloc(schema) : NULL;
|
||||
avrofile->filename = my_filename;
|
||||
avrofile->schema = maxavro_schema_alloc(schema);
|
||||
avrofile->last_error = MAXAVRO_ERR_NONE;
|
||||
|
||||
if (!schema || !avrofile->schema ||
|
||||
!maxavro_read_sync(file, avrofile->sync) ||
|
||||
!maxavro_read_datablock_start(avrofile))
|
||||
if (avrofile->schema &&
|
||||
maxavro_read_sync(file, avrofile->sync) &&
|
||||
maxavro_read_datablock_start(avrofile))
|
||||
{
|
||||
avrofile->header_end_pos = avrofile->block_start_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Failed to initialize avrofile.");
|
||||
free(avrofile->schema);
|
||||
free(avrofile);
|
||||
avrofile = NULL;
|
||||
maxavro_schema_free(avrofile->schema);
|
||||
error = true;
|
||||
}
|
||||
avrofile->header_end_pos = avrofile->block_start_pos;
|
||||
free(schema);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
fclose(file);
|
||||
free(avrofile);
|
||||
free(my_filename);
|
||||
avrofile = NULL;
|
||||
}
|
||||
|
||||
free(schema);
|
||||
|
||||
return avrofile;
|
||||
}
|
||||
|
||||
@ -248,19 +293,43 @@ void maxavro_file_close(MAXAVRO_FILE *file)
|
||||
GWBUF* maxavro_file_binary_header(MAXAVRO_FILE *file)
|
||||
{
|
||||
long pos = file->header_end_pos;
|
||||
fseek(file->file, 0, SEEK_SET);
|
||||
GWBUF *rval = gwbuf_alloc(pos);
|
||||
if (rval)
|
||||
GWBUF *rval = NULL;
|
||||
|
||||
if (fseek(file->file, 0, SEEK_SET) == 0)
|
||||
{
|
||||
if (fread(GWBUF_DATA(rval), 1, pos, file->file) != pos)
|
||||
if ((rval = gwbuf_alloc(pos)))
|
||||
{
|
||||
gwbuf_free(rval);
|
||||
rval = NULL;
|
||||
if (fread(GWBUF_DATA(rval), 1, pos, file->file) != pos)
|
||||
{
|
||||
if (ferror(file->file))
|
||||
{
|
||||
char err[STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to read binary header: %d, %s", errno,
|
||||
strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else if (feof(file->file))
|
||||
{
|
||||
MXS_ERROR("Short read when reading binary header.");
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Unspecified error when reading binary header.");
|
||||
}
|
||||
gwbuf_free(rval);
|
||||
rval = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Memory allocation failed when allocating %ld bytes.", pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Memory allocation failed when allocating %ld bytes.", pos);
|
||||
char err[STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to read binary header: %d, %s", errno,
|
||||
strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
|
||||
if (rval)
|
||||
{
|
||||
bool error = false;
|
||||
json_error_t err;
|
||||
json_t *schema = json_loads(json, 0, &err);
|
||||
|
||||
@ -139,7 +140,7 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
char *key;
|
||||
json_t *value_obj;
|
||||
|
||||
if (json_unpack(object, "{s:s s:o}", "name", &key, "type", &value_obj) == 0)
|
||||
if (object && json_unpack(object, "{s:s s:o}", "name", &key, "type", &value_obj) == 0)
|
||||
{
|
||||
rval->fields[i].name = strdup(key);
|
||||
rval->fields[i].type = unpack_to_type(value_obj, &rval->fields[i]);
|
||||
@ -147,26 +148,41 @@ MAXAVRO_SCHEMA* maxavro_schema_alloc(const char* json)
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Failed to unpack JSON Object \"name\": %s", json);
|
||||
error = true;
|
||||
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
free(rval->fields[j].name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Failed to unpack JSON Object \"fields\": %s", json);
|
||||
error = true;
|
||||
}
|
||||
|
||||
|
||||
json_decref(schema);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Failed to read JSON schema: %s", json);
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
free(rval);
|
||||
rval = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Memory allocation failed.");
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user