Skip to content

Commit 35b74b8

Browse files
committed
Improved error handling.
1 parent 5d50687 commit 35b74b8

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

postgres_protobuf.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ Datum protobuf_to_json_text(PG_FUNCTION_ARGS) {
248248
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
249249
errmsg("invalid query: protobuf type %s not found",
250250
protobuf_type_str.c_str())));
251+
} catch (...) {
252+
ereport(ERROR,
253+
(errcode(ERRCODE_INTERNAL_ERROR),
254+
errmsg("unknown C++ exception in postgres_protobuf extension")));
251255
}
252256
}
253257

@@ -283,6 +287,10 @@ Datum protobuf_from_json_text(PG_FUNCTION_ARGS) {
283287
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
284288
errmsg("invalid query: protobuf type %s not found",
285289
protobuf_type_str.c_str())));
290+
} catch (...) {
291+
ereport(ERROR,
292+
(errcode(ERRCODE_INTERNAL_ERROR),
293+
errmsg("unknown C++ exception in postgres_protobuf extension")));
286294
}
287295
}
288296

querying.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,9 @@ const pb::Descriptor* QueryImpl::GetDesc(const descriptor_db::DescSet& desc_set,
10571057
std::string::size_type* query_start) {
10581058
std::string::size_type i = query.find(':', *query_start);
10591059
if (i == std::string::npos) {
1060-
throw BadQuery("invalid protobuf query - expected: [<descriptor_set>:]<message_name>:<path>");
1060+
throw BadQuery(
1061+
"invalid protobuf query - expected: "
1062+
"[<descriptor_set>:]<message_name>:<path>");
10611063
}
10621064
std::string desc_name(query.substr(*query_start, i - *query_start));
10631065
*query_start = i + 1;
@@ -1075,7 +1077,8 @@ void QueryImpl::CompileQueryPart(const pb::Descriptor** desc,
10751077
const pb::EnumDescriptor** ed,
10761078
const std::string& part) {
10771079
if (*desc == nullptr) {
1078-
throw BadQuery(std::string("query does not refer to a known field: ") + part);
1080+
throw BadQuery(std::string("query does not refer to a known field: ") +
1081+
part);
10791082
}
10801083

10811084
if (part.empty()) {
@@ -1128,8 +1131,8 @@ void QueryImpl::CompileQueryPart(const pb::Descriptor** desc,
11281131
if (fd->is_repeated()) {
11291132
std::string rep_selector = part.substr(field_selector_end);
11301133

1131-
bool bracketed =
1132-
rep_selector[0] == '[' && rep_selector[rep_selector.size() - 1] == ']';
1134+
bool bracketed = rep_selector.size() > 0 && rep_selector.at(0) == '[' &&
1135+
rep_selector[rep_selector.size() - 1] == ']';
11331136
bool keys_selector = rep_selector == "|keys";
11341137
if (!bracketed && !keys_selector) {
11351138
throw BadQuery(std::string(
@@ -1207,12 +1210,18 @@ void QueryImpl::CompileQueryPart(const pb::Descriptor** desc,
12071210

12081211
if (rep_selector != "*") {
12091212
size_t end;
1210-
long n = std::stol(rep_selector.c_str(), &end, 10);
1211-
if (end != rep_selector.size()) {
1212-
throw BadQuery(std::string("expected numeric indexer at: ") + rep_selector);
1213+
long n;
1214+
try {
1215+
n = std::stol(rep_selector.c_str(), &end, 10);
1216+
} catch (const std::invalid_argument& e) {
1217+
throw BadQuery(std::string("invalid numeric key: ") + rep_selector);
1218+
} catch (const std::out_of_range& e) {
1219+
throw BadQuery(std::string("numeric key out of range key type: ") +
1220+
rep_selector);
12131221
}
1214-
if (n < 0 || n > static_cast<long>(std::numeric_limits<int>::max())) {
1215-
throw BadQuery(std::string("index out of bounds: " + rep_selector));
1222+
if (end != rep_selector.size()) {
1223+
throw BadQuery(std::string("expected numeric indexer at: ") +
1224+
rep_selector);
12161225
}
12171226

12181227
field_selector->SetWantedIndex(static_cast<int>(n));
@@ -1229,16 +1238,16 @@ T ParseNum(const std::string& s) {
12291238
typename std::conditional<std::is_unsigned_v<T>, unsigned long long,
12301239
signed long long>::type;
12311240
Tmp tmp;
1232-
if constexpr (std::is_unsigned_v<T>) {
1233-
tmp = std::stoull(s, &end);
1234-
} else {
1235-
tmp = std::stoll(s, &end);
1236-
}
1237-
if (tmp < std::numeric_limits<T>::min()) {
1238-
throw BadQuery(std::string("numeric key too small for key type: ") + s);
1239-
}
1240-
if (tmp > std::numeric_limits<T>::max()) {
1241-
throw BadQuery(std::string("numeric key too large for key type: ") + s);
1241+
try {
1242+
if constexpr (std::is_unsigned_v<T>) {
1243+
tmp = std::stoull(s, &end);
1244+
} else {
1245+
tmp = std::stoll(s, &end);
1246+
}
1247+
} catch (const std::invalid_argument& e) {
1248+
throw BadQuery(std::string("invalid numeric key: ") + s);
1249+
} catch (const std::out_of_range& e) {
1250+
throw BadQuery(std::string("numeric key out of range key type: ") + s);
12421251
}
12431252
if (end != s.size()) {
12441253
throw BadQuery(std::string("invalid numeric key: ") + s);

0 commit comments

Comments
 (0)