From cadc670c0d1f61a8e42154837124542749f0c4cd Mon Sep 17 00:00:00 2001 From: Michael Jurkoic Date: Sun, 14 Apr 2024 14:41:25 -0500 Subject: Improve error handling around JSON parsing --- src/event.cpp | 33 +++++++++++++++++++++++++-------- src/nostr_service.cpp | 23 +++++++++++++++++------ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/event.cpp b/src/event.cpp index 532ba81..7b5bfb2 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -12,6 +12,7 @@ using nlohmann::json; using std::hex; using std::invalid_argument; using std::make_shared; +using std::ostringstream; using std::setw; using std::setfill; using std::shared_ptr; @@ -49,21 +50,37 @@ string Event::serialize() Event Event::fromString(string jstr) { json j = json::parse(jstr); + Event event; - return Event::fromJson(j); + try + { + event = Event::fromJson(j); + } + catch (const invalid_argument& e) + { + throw e; + } + + return event; }; Event Event::fromJson(json j) { Event event; - event.id = j["id"]; - event.pubkey = j["pubkey"]; - event.createdAt = j["created_at"]; - event.kind = j["kind"]; - event.tags = j["tags"]; - event.content = j["content"]; - event.sig = j["sig"]; + try { + event.id = j.at("id"); + event.pubkey = j.at("pubkey"); + event.createdAt = j.at("created_at"); + event.kind = j.at("kind"); + event.tags = j.at("tags"); + event.content = j.at("content"); + event.sig = j.at("sig"); + } catch (const json::out_of_range& e) { + ostringstream oss; + oss << "Event::fromJson: Tried to access an out-of-range element: " << e.what(); + throw invalid_argument(oss.str()); + } return event; }; diff --git a/src/nostr_service.cpp b/src/nostr_service.cpp index 5b32beb..91e662e 100644 --- a/src/nostr_service.cpp +++ b/src/nostr_service.cpp @@ -19,6 +19,7 @@ using std::async; using std::find_if; using std::function; using std::future; +using std::invalid_argument; using std::lock_guard; using std::make_shared; using std::make_tuple; @@ -536,30 +537,40 @@ void NostrService::onSubscriptionMessage( try { json jMessage = json::parse(message); - string messageType = jMessage[0]; + string messageType = jMessage.at(0); if (messageType == "EVENT") { - string subscriptionId = jMessage[1]; - Event event = Event::fromString(jMessage[2]); + string subscriptionId = jMessage.at(1); + Event event = Event::fromString(jMessage.at(2)); eventHandler(subscriptionId, make_shared(event)); } else if (messageType == "EOSE") { - string subscriptionId = jMessage[1]; + string subscriptionId = jMessage.at(1); eoseHandler(subscriptionId); } else if (messageType == "CLOSE") { - string subscriptionId = jMessage[1]; - string reason = jMessage[2]; + string subscriptionId = jMessage.at(1); + string reason = jMessage.at(2); closeHandler(subscriptionId, reason); } } + catch (const json::out_of_range& joor) + { + PLOG_ERROR << "JSON out-of-range exception: " << joor.what(); + throw joor; + } catch (const json::exception& je) { PLOG_ERROR << "JSON handling exception: " << je.what(); throw je; } + catch (const invalid_argument& ia) + { + PLOG_ERROR << "Invalid argument exception: " << ia.what(); + throw ia; + } }; void NostrService::onAcceptance(string message, function acceptanceHandler) -- cgit