Enumerate more error conditions

This commit is contained in:
Erica Fischer 2022-09-13 16:53:05 -07:00
parent 02617c89fe
commit ddc7f31f88
5 changed files with 81 additions and 42 deletions

@ -985,3 +985,42 @@ Error returns
* 135: Impossible zoom level in mbtiles file
* 136: Can't close mbtiles file after enumerating
* 137: Unrecognized command line option for tippecanoe-enumerate
* 138: Corrupt attribute type in expression evaluation
* 139: Corrupt attribute type in expression evaluation
* 140: Filter is not in the form of an array
* 141: Filter is in the form of an empty array
* 142: Filter operation is not a string
* 143: Wrong number of arguments for "has" filter operation
* 144: Has filter key is not a string
* 145: !Has filter key is not a string
* 146: Wrong number of arguments for comparison filter operation
* 147: Comparison filter key is not a string
* 148: Impossible filter comparison operation
* 149: Wrong number of arguments for "in" filter operation
* 150: In filter key is not a string
* 151: Wrong number arguments for attribute-filter filter operation
* 152: Attribute-filter key is not a string
* 153: Unknown filter operation
* 154: List of filters is not a JSON object
* 155: Error opening filter file
* 156: Error reading JSON from filter file
* 157: Error parsing JSON from filter string
* 158: Unsupported geometry type in flatgeobuf file
* 159: Unsupported geometry type in flatgeobuf file
* 160: Flatgeobuf attribute type can't be represented in vector tiles
* 161: Error creating feature parsing thread for flatgeobuf features
* 162: Flatgeobuf header has the wrong magic number
* 163: Flatgeobuf feature can't be verified
* 164: Geobuf geometry has fewer than 2 dimensions
* 165: Impossible geobuf line segment index
* 166: Out-of-bounds geobuf key index
* 167: Out-of-bounds geobuf value index
* 168: Out-of-bounds geobuf key index
* 169: Out-of-bounds geobuf value index
* 170: Error creating geobuf feature parsing thread
* 171: Error opening file of CSV features
* 172: UTF-8 parsing error in header of CSV feature file
* 173: Can't find latitude and longitude columns in CSV feature file
* 174: UTF-8 parsing error in body of CSV feature file
* 175: Inconsistent number of columns in CSV feature file
* 176: Can't close CSV feature file

@ -34,7 +34,7 @@ int compare(mvt_value one, json_object *two, bool &fail) {
v = one.numeric_value.sint_value;
} else {
fprintf(stderr, "Internal error: bad mvt type %d\n", one.type);
exit(EXIT_FAILURE);
exit(138);
}
if (v < two->value.number.number) {
@ -66,36 +66,36 @@ int compare(mvt_value one, json_object *two, bool &fail) {
}
fprintf(stderr, "Internal error: bad mvt type %d\n", one.type);
exit(EXIT_FAILURE);
exit(139);
}
bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::set<std::string> &exclude_attributes) {
if (f == NULL || f->type != JSON_ARRAY) {
fprintf(stderr, "Filter is not an array: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(140);
}
if (f->value.array.length < 1) {
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(141);
}
if (f->value.array.array[0]->type != JSON_STRING) {
fprintf(stderr, "Filter operation is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(142);
}
if (strcmp(f->value.array.array[0]->value.string.string, "has") == 0 ||
strcmp(f->value.array.array[0]->value.string.string, "!has") == 0) {
if (f->value.array.length != 2) {
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(143);
}
if (strcmp(f->value.array.array[0]->value.string.string, "has") == 0) {
if (f->value.array.array[1]->type != JSON_STRING) {
fprintf(stderr, "\"has\" key is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(144);
}
return feature.count(std::string(f->value.array.array[1]->value.string.string)) != 0;
}
@ -103,7 +103,7 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
if (strcmp(f->value.array.array[0]->value.string.string, "!has") == 0) {
if (f->value.array.array[1]->type != JSON_STRING) {
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(145);
}
return feature.count(std::string(f->value.array.array[1]->value.string.string)) == 0;
}
@ -117,11 +117,11 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
strcmp(f->value.array.array[0]->value.string.string, "<=") == 0) {
if (f->value.array.length != 3) {
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(146);
}
if (f->value.array.array[1]->type != JSON_STRING) {
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
fprintf(stderr, "comparison key is not a string: %s\n", json_stringify(f));
exit(147);
}
auto ff = feature.find(std::string(f->value.array.array[1]->value.string.string));
@ -176,7 +176,7 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
}
fprintf(stderr, "Internal error: can't happen: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(148);
}
if (strcmp(f->value.array.array[0]->value.string.string, "all") == 0 ||
@ -217,12 +217,12 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
strcmp(f->value.array.array[0]->value.string.string, "!in") == 0) {
if (f->value.array.length < 2) {
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(149);
}
if (f->value.array.array[1]->type != JSON_STRING) {
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
fprintf(stderr, "\"in\" key is not a string: %s\n", json_stringify(f));
exit(150);
}
auto ff = feature.find(std::string(f->value.array.array[1]->value.string.string));
@ -272,12 +272,12 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
if (strcmp(f->value.array.array[0]->value.string.string, "attribute-filter") == 0) {
if (f->value.array.length != 3) {
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(151);
}
if (f->value.array.array[1]->type != JSON_STRING) {
fprintf(stderr, "\"attribute-filter\" key is not a string: %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(152);
}
bool ok = eval(feature, f->value.array.array[2], exclude_attributes);
@ -289,13 +289,13 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f, std::
}
fprintf(stderr, "Unknown filter %s\n", json_stringify(f));
exit(EXIT_FAILURE);
exit(153);
}
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_object *filter, std::set<std::string> &exclude_attributes) {
if (filter == NULL || filter->type != JSON_HASH) {
fprintf(stderr, "Error: filter is not a hash: %s\n", json_stringify(filter));
exit(EXIT_FAILURE);
exit(154);
}
bool ok = true;
@ -318,14 +318,14 @@ json_object *read_filter(const char *fname) {
FILE *fp = fopen(fname, "r");
if (fp == NULL) {
perror(fname);
exit(EXIT_FAILURE);
exit(155);
}
json_pull *jp = json_begin_file(fp);
json_object *filter = json_read_tree(jp);
if (filter == NULL) {
fprintf(stderr, "%s: %s\n", fname, jp->error);
exit(EXIT_FAILURE);
exit(156);
}
json_disconnect(filter);
json_end(jp);
@ -339,7 +339,7 @@ json_object *parse_filter(const char *s) {
if (filter == NULL) {
fprintf(stderr, "Could not parse filter %s\n", s);
fprintf(stderr, "%s\n", jp->error);
exit(EXIT_FAILURE);
exit(157);
}
json_disconnect(filter);
json_end(jp);

@ -95,7 +95,7 @@ drawvec readGeometry(const FlatGeobuf::Geometry *geometry, FlatGeobuf::GeometryT
return dv;
} else {
fprintf(stderr, "flatgeobuf has unsupported geometry type %u\n", (unsigned int)h_geometry_type);
exit(EXIT_FAILURE);
exit(158);
}
}
@ -124,7 +124,7 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_
case FlatGeobuf::GeometryType::GeometryCollection :
default:
fprintf(stderr, "flatgeobuf has unsupported geometry type %u\n", (unsigned int)h_geometry_type);
exit(EXIT_FAILURE);
exit(159);
}
serial_feature sf;
@ -236,7 +236,7 @@ void readFeature(const FlatGeobuf::Feature *feature, long long feature_sequence_
} else {
// Binary is not representable in MVT
fprintf(stderr, "flatgeobuf has unsupported column type %u\n", (unsigned int)col_type);
exit(EXIT_FAILURE);
exit(160);
}
full_keys.push_back(h_column_names[col_idx]);
full_values.push_back(sv);
@ -304,7 +304,7 @@ void fgbRunQueue() {
for (size_t i = 0; i < CPUS; i++) {
if (pthread_create(&pthreads[i], NULL, fgb_run_parse_feature, &qra[i]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
exit(161);
}
}
@ -347,7 +347,7 @@ void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *
const auto ok = FlatGeobuf::VerifySizePrefixedHeaderBuffer(v);
if (!ok) {
fprintf(stderr, "flatgeobuf header verification failed\n");
exit(EXIT_FAILURE);
exit(162);
}
auto header = FlatGeobuf::GetSizePrefixedHeader(src + sizeof(magicbytes));
@ -384,7 +384,7 @@ void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *
const auto ok2 = FlatGeobuf::VerifySizePrefixedFeatureBuffer(v2);
if (!ok2) {
fprintf(stderr, "flatgeobuf feature buffer verification failed\n");
exit(EXIT_FAILURE);
exit(163);
}
auto feature = FlatGeobuf::GetSizePrefixedFeature(start);
@ -396,4 +396,4 @@ void parse_flatgeobuf(std::vector<struct serialization_state> *sst, const char *
}
fgbRunQueue();
}
}

@ -37,7 +37,7 @@ static std::vector<queued_feature> feature_queue;
void ensureDim(size_t dim) {
if (dim < 2) {
fprintf(stderr, "Geometry has fewer than 2 dimensions: %zu\n", dim);
exit(EXIT_FAILURE);
exit(164);
}
}
@ -117,7 +117,7 @@ drawvec readLinePart(std::vector<long long> &coords, size_t dim, double e, size_
for (size_t i = start; i + dim - 1 < end; i += dim) {
if (i + dim - 1 >= coords.size()) {
fprintf(stderr, "Internal error: line segment %zu vs %zu\n", i + dim - 1, coords.size());
exit(EXIT_FAILURE);
exit(165);
}
for (size_t d = 0; d < dim; d++) {
@ -328,12 +328,12 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
for (size_t i = 0; i + 1 < properties.size(); i += 2) {
if (properties[i] >= keys.size()) {
fprintf(stderr, "Out of bounds key: %zu in %zu\n", properties[i], keys.size());
exit(EXIT_FAILURE);
exit(166);
}
if (properties[i + 1] >= values.size()) {
fprintf(stderr, "Out of bounds value: %zu in %zu\n", properties[i + 1], values.size());
exit(EXIT_FAILURE);
exit(167);
}
full_keys.push_back(keys[properties[i]]);
@ -354,12 +354,12 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
for (size_t i = 0; i + 1 < misc.size(); i += 2) {
if (misc[i] >= keys.size()) {
fprintf(stderr, "Out of bounds key: %zu in %zu\n", misc[i], keys.size());
exit(EXIT_FAILURE);
exit(168);
}
if (misc[i + 1] >= values.size()) {
fprintf(stderr, "Out of bounds value: %zu in %zu\n", misc[i + 1], values.size());
exit(EXIT_FAILURE);
exit(169);
}
other.insert(std::pair<std::string, serial_val>(keys[misc[i]], values[misc[i + 1]]));
@ -466,7 +466,7 @@ void runQueue() {
for (size_t i = 0; i < CPUS; i++) {
if (pthread_create(&pthreads[i], NULL, run_parse_feature, &qra[i]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
exit(170);
}
}

@ -19,7 +19,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
f = fopen(fname.c_str(), "r");
if (f == NULL) {
perror(fname.c_str());
exit(EXIT_FAILURE);
exit(171);
}
}
@ -31,7 +31,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
std::string err = check_utf8(s);
if (err != "") {
fprintf(stderr, "%s: %s\n", fname.c_str(), err.c_str());
exit(EXIT_FAILURE);
exit(172);
}
header = csv_split(s.c_str());
@ -53,7 +53,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
if (latcol < 0 || loncol < 0) {
fprintf(stderr, "%s: Can't find \"lat\" and \"lon\" columns\n", fname.c_str());
exit(EXIT_FAILURE);
exit(173);
}
size_t seq = 0;
@ -61,7 +61,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
std::string err = check_utf8(s);
if (err != "") {
fprintf(stderr, "%s: %s\n", fname.c_str(), err.c_str());
exit(EXIT_FAILURE);
exit(174);
}
seq++;
@ -69,7 +69,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
if (line.size() != header.size()) {
fprintf(stderr, "%s:%zu: Mismatched column count: %zu in line, %zu in header\n", fname.c_str(), seq + 1, line.size(), header.size());
exit(EXIT_FAILURE);
exit(175);
}
if (line[loncol].empty() || line[latcol].empty()) {
@ -133,7 +133,7 @@ void parse_geocsv(std::vector<struct serialization_state> &sst, std::string fnam
if (fname.size() != 0) {
if (fclose(f) != 0) {
perror("fclose");
exit(EXIT_FAILURE);
exit(176);
}
}
}