diff --git a/jstests/core/throw_big.js b/jstests/core/throw_big.js new file mode 100644 index 00000000000..422ee93a6ae --- /dev/null +++ b/jstests/core/throw_big.js @@ -0,0 +1,16 @@ +/** + * Test that verifies the javascript integration can handle large string exception messages. + */ +(function() { + 'use strict'; + + var len = 65 * 1024 * 1024; + var str = new Array(len + 1).join('b'); + + // We expect to successfully throw and catch this large exception message. + // We do not want the mongo shell to terminate. + assert.throws(function() { + throw str; + }); + +})(); diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp index 3a8fb1e2d18..399a1e532f9 100644 --- a/src/mongo/scripting/mozjs/implscope.cpp +++ b/src/mongo/scripting/mozjs/implscope.cpp @@ -123,29 +123,39 @@ void MozJSImplScope::_reportError(JSContext* cx, const char* message, JSErrorRep auto scope = getScope(cx); if (!JSREPORT_IS_WARNING(report->flags)) { - str::stream ss; - ss << message; - // TODO: something far more elaborate that mimics the stack printing from v8 - JS::RootedValue excn(cx); - if (JS_GetPendingException(cx, &excn) && excn.isObject()) { - JS::RootedValue stack(cx); + std::string exceptionMsg; - ObjectWrapper(cx, excn).getValue("stack", &stack); + try { + str::stream ss; + ss << message; - auto str = ValueWriter(cx, stack).toString(); + // TODO: something far more elaborate that mimics the stack printing from v8 + JS::RootedValue excn(cx); + if (JS_GetPendingException(cx, &excn) && excn.isObject()) { + JS::RootedValue stack(cx); - if (str.empty()) { - ss << " @" << report->filename << ":" << report->lineno << ":" << report->column - << "\n"; - } else { - ss << " :\n" << str; + ObjectWrapper(cx, excn).getValue("stack", &stack); + + auto str = ValueWriter(cx, stack).toString(); + + if (str.empty()) { + ss << " @" << report->filename << ":" << report->lineno << ":" << report->column + << "\n"; + } else { + ss << " :\n" << str; + } } + + exceptionMsg = ss; + } catch (const DBException& dbe) { + exceptionMsg = "Unknown error occured while processing exception"; + log() << exceptionMsg << ":" << dbe.toString() << ":" << message; } scope->_status = Status( JSErrorReportToStatus(cx, report, ErrorCodes::JSInterpreterFailure, message).code(), - ss); + exceptionMsg); } }