diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llcoros.cpp | 7 | ||||
-rw-r--r-- | indra/llcommon/llevents.h | 32 | ||||
-rw-r--r-- | indra/llcommon/llexception.cpp | 4 | ||||
-rw-r--r-- | indra/llcommon/tests/llerror_test.cpp | 17 |
4 files changed, 49 insertions, 11 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 4ee8e6d796..4db63937aa 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -240,12 +240,17 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla { callable(); } - catch (const LLContinueError& e) + catch (const LLContinueError&) { + // Any uncaught exception derived from LLContinueError will be caught + // here and logged. This coroutine will terminate but the rest of the + // viewer will carry on. LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); } catch (...) { + // Any OTHER kind of uncaught exception will cause the viewer to + // crash, hopefully informatively. CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); } // This cleanup isn't perfectly symmetrical with the way we initially set diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 8ff337911d..1526128725 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -95,12 +95,32 @@ struct LLStopWhenHandled result_type operator()(InputIterator first, InputIterator last) const { for (InputIterator si = first; si != last; ++si) - { - if (*si) - { - return true; - } - } + { + try + { + if (*si) + { + return true; + } + } + catch (const LLContinueError&) + { + // We catch LLContinueError here because an LLContinueError- + // based exception means the viewer as a whole should carry on + // to the best of our ability. Therefore subsequent listeners + // on the same LLEventPump should still receive this event. + + // The iterator passed to a boost::signals2 Combiner is very + // clever, but provides no contextual information. We would + // very much like to be able to log the name of the LLEventPump + // plus the name of this particular listener, but alas. + LOG_UNHANDLED_EXCEPTION("LLEventPump"); + } + // We do NOT catch (...) here because we might as well let it + // propagate out to the generic handler. If we were able to log + // context information here, that would be great, but we can't, so + // there's no point. + } return false; } }; diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 791b115a8c..1c39c0f827 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -29,8 +29,8 @@ void log_unhandled_exception_(LLError::ELevel level, { // log same message but allow caller-specified severity level // lllog() is the macro underlying LL_ERRS(), LL_WARNS() et al. - lllog(level, false) << file << "(" << line << "): Unhandled exception caught in " - << pretty_function; + lllog(level, false, "LLException") + << file << "(" << line << "): Unhandled exception caught in " << pretty_function; if (! context.empty()) { LL_CONT << ": " << context; diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index f51279e817..8bace8ac41 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -237,8 +237,21 @@ namespace tut void ErrorTestObject::test<4>() // file abbreviation { - std::string thisFile = __FILE__; - std::string abbreviateFile = LLError::abbreviateFile(thisFile); + std::string prev, abbreviateFile = __FILE__; + do + { + prev = abbreviateFile; + abbreviateFile = LLError::abbreviateFile(abbreviateFile); + // __FILE__ is assumed to end with + // indra/llcommon/tests/llerror_test.cpp. This test used to call + // abbreviateFile() exactly once, then check below whether it + // still contained the string 'indra'. That fails if the FIRST + // part of the pathname also contains indra! Certain developer + // machine images put local directory trees under + // /ngi-persist/indra, which is where we observe the problem. So + // now, keep calling abbreviateFile() until it returns its + // argument unchanged, THEN check. + } while (abbreviateFile != prev); ensure_ends_with("file name abbreviation", abbreviateFile, |