summaryrefslogtreecommitdiff
path: root/indra/llcommon/llleap.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2023-01-23 10:51:33 -0500
committerNat Goodspeed <nat@lindenlab.com>2023-07-13 12:49:09 -0400
commit2eb0ea9593d0e299445d2e1dde711bfe5072542e (patch)
treea64768f1b6b2a2a6fc64940e96ba99d12a7cb59c /indra/llcommon/llleap.cpp
parentc747ff0925fb85147a96745bb55e66e7e8004fd8 (diff)
DRTVWR-558: Nail down LLDispatchListener exception handling
for exceptions other than those thrown by base-class LLEventDispatcher. Explain in LLDispatchListener Doxygen comments that for a request lacking a "reply" key, any exception is allowed to propagate because it's likely to reach the post() call that triggered the exception in the first place. For batch LLDispatchListener operations, catch not only LLEventDispatcher:: DispatchError exceptions but any std::exception, so we can collect them to report to the invoker. "Gotta catch 'em all!" Make LLLeap catch any std::exception thrown by processing a request from the plugin child process, log it and send a reply to the plugin. No plugin should be allowed to crash the viewer. (cherry picked from commit 94e10fd039b79f71ed8d7e10807b6e4eebd1928c)
Diffstat (limited to 'indra/llcommon/llleap.cpp')
-rw-r--r--indra/llcommon/llleap.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index c87c0758fe..abbc4185c6 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -327,11 +327,28 @@ public:
}
else
{
- // The LLSD object we got from our stream contains the keys we
- // need.
- LLEventPumps::instance().obtain(data["pump"]).post(data["data"]);
- // Block calls to this method; resetting mBlocker unblocks calls
- // to the other method.
+ try
+ {
+ // The LLSD object we got from our stream contains the
+ // keys we need.
+ LLEventPumps::instance().obtain(data["pump"]).post(data["data"]);
+ }
+ catch (const std::exception& err)
+ {
+ // No plugin should be allowed to crash the viewer by
+ // driving an exception -- intentionally or not.
+ LOG_UNHANDLED_EXCEPTION(stringize("handling request ", data));
+ // Whether or not the plugin added a "reply" key to the
+ // request, send a reply. We happen to know who originated
+ // this request, and the reply LLEventPump of interest.
+ // Not our problem if the plugin ignores the reply event.
+ data["reply"] = mReplyPump.getName();
+ sendReply(llsd::map("error",
+ stringize(LLError::Log::classname(err), ": ", err.what())),
+ data);
+ }
+ // Block calls to this method; resetting mBlocker unblocks
+ // calls to the other method.
mBlocker.reset(new LLEventPump::Blocker(mStdoutDataConnection));
// Go check for any more pending events in the buffer.
if (childout.size())