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
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
module = ModuleCache[path] = new Module(path);
content = "(function (module, exports, require, print) {"
+ raw.content
+ "\n});";
f = SYS_EXECUTE(content, undefined, path);
if (f === undefined) {
throw "cannot create context function";
}
f(module,
module.exports,
function(path) { return module.require(path); },
ModuleCache["/internal"].exports.print);
try {
f(module,
module.exports,
function(path) { return module.require(path); },
ModuleCache["/internal"].exports.print);
}
catch (err) {
throw "Javascript exception in file '" + path + "': " + err.stack;
}
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);
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;
}
@ -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
///
@ -558,7 +606,7 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
if (! source->IsString()) {
return scope.Close(v8::ThrowException(v8::String::New("<script> must be a string")));
}
bool useSandbox = sandboxValue->IsObject();
v8::Handle<v8::Object> sandbox;
v8::Handle<v8::Context> context;
@ -602,7 +650,7 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
context->DetachGlobal();
context->Exit();
}
return scope.Close(v8::Undefined());
}
@ -1600,6 +1648,10 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context, string const& path) {
// .............................................................................
// 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"),
v8::FunctionTemplate::New(JS_Execute)->GetFunction(),