1
0
Fork 0

issue #262: more verbose error messages when loading broken modules

This commit is contained in:
Jan Steemann 2012-10-22 16:20:07 +02:00
parent 56cd3327a6
commit d4cb1b5399
2 changed files with 71 additions and 9 deletions

View File

@ -87,23 +87,33 @@ Module.prototype.require = function (path) {
// locate file and read content // locate file and read content
raw = ModuleCache["/internal"].exports.readFile(path); raw = ModuleCache["/internal"].exports.readFile(path);
// test for parse errors first and fail early if a parse error detected
if (! SYS_PARSE(raw.content, path)) {
throw "Javascript parse error in file '" + path + "'";
}
// create a new sandbox and execute // create a new sandbox and execute
module = ModuleCache[path] = new Module(path); module = ModuleCache[path] = new Module(path);
content = "(function (module, exports, require, print) {" content = "(function (module, exports, require, print) {"
+ raw.content + raw.content
+ "\n});"; + "\n});";
f = SYS_EXECUTE(content, undefined, path); f = SYS_EXECUTE(content, undefined, path);
if (f === undefined) { if (f === undefined) {
throw "cannot create context function"; throw "cannot create context function";
} }
f(module, try {
module.exports, f(module,
function(path) { return module.require(path); }, module.exports,
ModuleCache["/internal"].exports.print); function(path) { return module.require(path); },
ModuleCache["/internal"].exports.print);
}
catch (err) {
throw "Javascript exception in file '" + path + "': " + err.stack;
}
return module.exports; return module.exports;
}; };

View File

@ -430,7 +430,7 @@ static bool LoadJavaScriptFile (v8::Handle<v8::Context> context,
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, filename); char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, filename);
if (content == 0) { if (content == 0) {
LOG_TRACE("cannot loaded java script file '%s': %s", filename, TRI_last_error()); LOG_TRACE("cannot load java script file '%s': %s", filename, TRI_last_error());
return false; return false;
} }
@ -529,6 +529,54 @@ static bool LoadJavaScriptDirectory (v8::Handle<v8::Context> context, char const
/// @{ /// @{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief parse a Javascript snippet, but do not execute it
///
/// @FUN{internal.parse(@FA{script})}
///
/// Parses the @FA{script} code, but does not execute it.
/// Will return @LIT{true} if the code does not have a parse error, and throw
/// an exception otherwise.
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_Parse (v8::Arguments const& argv) {
v8::HandleScope scope;
v8::TryCatch tryCatch;
if (argv.Length() < 1) {
return scope.Close(v8::ThrowException(v8::String::New("usage: parse(<script>)")));
}
v8::Handle<v8::Value> source = argv[0];
v8::Handle<v8::Value> filename;
if (argv.Length() > 1) {
filename = argv[1];
}
else {
filename = v8::String::New("(snippet)");
}
if (! source->IsString()) {
return scope.Close(v8::ThrowException(v8::String::New("<script> must be a string")));
}
v8::Handle<v8::Script> script = v8::Script::Compile(source->ToString(), filename);
// compilation failed, we have caught an exception
if (tryCatch.HasCaught()) {
string err = TRI_StringifyV8Exception(&tryCatch);
return scope.Close(v8::ThrowException(v8::String::New(err.c_str())));
}
// compilation failed, we don't know why
if (script.IsEmpty()) {
return scope.Close(v8::False());
}
return scope.Close(v8::True());
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief executes a script /// @brief executes a script
/// ///
@ -558,7 +606,7 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
if (! source->IsString()) { if (! source->IsString()) {
return scope.Close(v8::ThrowException(v8::String::New("<script> must be a string"))); return scope.Close(v8::ThrowException(v8::String::New("<script> must be a string")));
} }
bool useSandbox = sandboxValue->IsObject(); bool useSandbox = sandboxValue->IsObject();
v8::Handle<v8::Object> sandbox; v8::Handle<v8::Object> sandbox;
v8::Handle<v8::Context> context; v8::Handle<v8::Context> context;
@ -602,7 +650,7 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
context->DetachGlobal(); context->DetachGlobal();
context->Exit(); context->Exit();
} }
return scope.Close(v8::Undefined()); return scope.Close(v8::Undefined());
} }
@ -1600,6 +1648,10 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context, string const& path) {
// ............................................................................. // .............................................................................
// create the global functions // create the global functions
// ............................................................................. // .............................................................................
context->Global()->Set(v8::String::New("SYS_PARSE"),
v8::FunctionTemplate::New(JS_Parse)->GetFunction(),
v8::ReadOnly);
context->Global()->Set(v8::String::New("SYS_EXECUTE"), context->Global()->Set(v8::String::New("SYS_EXECUTE"),
v8::FunctionTemplate::New(JS_Execute)->GetFunction(), v8::FunctionTemplate::New(JS_Execute)->GetFunction(),