Beispiel #1
0
void Script::translateException(const v8::TryCatch &tryCatch, bool useStack) {
  v8::HandleScope handleScope;

  if (useStack && !tryCatch.StackTrace().IsEmpty())
    throw Exception(Value(tryCatch.StackTrace()).toString());

  if (tryCatch.Exception()->IsNull()) throw Exception("Interrupted");

  string msg = Value(tryCatch.Exception()).toString();

  v8::Handle<v8::Message> message = tryCatch.Message();
  if (message.IsEmpty()) throw Exception(msg);

  string filename = Value(message->GetScriptResourceName()).toString();
  int line = message->GetLineNumber();
  int col = message->GetStartColumn();

  throw Exception(msg, FileLocation(filename, line, col));
}
Beispiel #2
0
std::string V8::ReportException(const v8::TryCatch& try_catch, bool suppressBacktrace) {
	v8::HandleScope handle_scope;
	std::string output = "";

	std::string exception_string = V8::StringToStdString(try_catch.Exception().As<String>());
	v8::Handle<v8::Message> message = try_catch.Message();

	if (suppressBacktrace || message.IsEmpty()) {

		// V8 didn't provide any extra information about this error; just
		// print the exception.
		output += exception_string;
		output += "\n";

	} else {

		output += V8::StringToStdString(
			message->GetScriptResourceName().As<String>()
		) + ":" + boost::lexical_cast<std::string>(
			message->GetLineNumber()
		) + "\n";

		output += exception_string + "\n";

		// Print line of source code.
		output += V8::StringToStdString(message->GetSourceLine()) + "\n";

		// Print wavy underline (GetUnderline is deprecated).
		int start = message->GetStartColumn();
		for (int i = 0; i < start; i++) {
			output += " ";
		}
		int end = message->GetEndColumn();
		for (int i = start; i < end; i++) {
			output += "^";
		}
		output += "\n";

		std::string stackTrace = V8::StringToStdString(try_catch.StackTrace().As<String>());
		if (stackTrace.length() > 0) {
			output += stackTrace + "\n";
		}
	}

	return output;
}
Beispiel #3
0
std::string stackTrace(const v8::TryCatch &try_catch)
{
  std::string stack_trace_str = "";

  v8::MaybeLocal<v8::Value> stack_trace_maybe = try_catch.StackTrace();

  if (!stack_trace_maybe.IsEmpty())
  {
    v8::Local<v8::Value> stack_trace = stack_trace_maybe.ToLocalChecked();

    if (stack_trace->IsString())
      stack_trace_str = v8cffi_utils::toCString(
        v8::String::Utf8Value(stack_trace));
  }

  return stack_trace_str;
}
Beispiel #4
0
/// @brief checks if a V8 exception has occurred and throws an appropriate C++
/// exception from it if so
void Executor::HandleV8Error(v8::TryCatch& tryCatch,
                             v8::Handle<v8::Value>& result,
                             arangodb::basics::StringBuffer* const buffer,
                             bool duringCompile) {
  ISOLATE;

  if (tryCatch.HasCaught()) {
    // caught a V8 exception
    if (!tryCatch.CanContinue()) {
      // request was canceled
      TRI_GET_GLOBALS();
      v8g->_canceled = true;

      THROW_ARANGO_EXCEPTION(TRI_ERROR_REQUEST_CANCELED);
    }

    // request was not canceled, but some other error occurred
    // peek into the exception
    if (tryCatch.Exception()->IsObject()) {
      // cast the exception to an object

      v8::Handle<v8::Array> objValue =
          v8::Handle<v8::Array>::Cast(tryCatch.Exception());
      v8::Handle<v8::String> errorNum = TRI_V8_ASCII_STRING("errorNum");
      v8::Handle<v8::String> errorMessage = TRI_V8_ASCII_STRING("errorMessage");

      TRI_Utf8ValueNFC stacktrace(TRI_UNKNOWN_MEM_ZONE, tryCatch.StackTrace());

      if (objValue->HasOwnProperty(errorNum) &&
          objValue->HasOwnProperty(errorMessage)) {
        v8::Handle<v8::Value> errorNumValue = objValue->Get(errorNum);
        v8::Handle<v8::Value> errorMessageValue = objValue->Get(errorMessage);

        // found something that looks like an ArangoError
        if ((errorNumValue->IsNumber() || errorNumValue->IsNumberObject()) &&
            (errorMessageValue->IsString() ||
             errorMessageValue->IsStringObject())) {
          int errorCode = static_cast<int>(TRI_ObjectToInt64(errorNumValue));
          std::string errorMessage(TRI_ObjectToString(errorMessageValue));

          if (*stacktrace && stacktrace.length() > 0) {
            errorMessage += "\nstacktrace of offending AQL function: ";
            errorMessage += *stacktrace;
          }

          THROW_ARANGO_EXCEPTION_MESSAGE(errorCode, errorMessage);
        }
      }

      // exception is no ArangoError
      std::string details(TRI_ObjectToString(tryCatch.Exception()));

      if (buffer) {
        std::string script(buffer->c_str(), buffer->length());
        LOG(ERR) << details << " " << script;
        details += "\nSee log for more details";
      }
      if (*stacktrace && stacktrace.length() > 0) {
        details += "\nstacktrace of offending AQL function: ";
        details += *stacktrace;
      }

      THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_SCRIPT, details);
    }

    std::string msg("unknown error in scripting");
    if (duringCompile) {
      msg += " (during compilation)";
    }
    if (buffer) {
      std::string script(buffer->c_str(), buffer->length());
      LOG(ERR) << msg << " " << script;
      msg += " See log for details";
    }
    // we can't figure out what kind of error occurred and throw a generic error
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg);
  }

  if (result.IsEmpty()) {
    std::string msg("unknown error in scripting");
    if (duringCompile) {
      msg += " (during compilation)";
    }
    if (buffer) {
      std::string script(buffer->c_str(), buffer->length());
      LOG(ERR) << msg << " " << script;
      msg += " See log for details";
    }

    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg);
  }

  // if we get here, no exception has been raised
}
Beispiel #5
0
static void reportException(v8::TryCatch &try_catch, bool show_line)
{
  using namespace v8;
  
  Handle<Message> message = try_catch.Message();

  v8::String::Utf8Value error(try_catch.Exception());
  if (error.length() > 0)
  {

    std::ostringstream errorMsg;

    /*
     02:50:22.863: [CID=00000000] JS: File undefined:12
    [CID=00000000] JS: Source Line   var notheetoo = nothere.subst(0, 10);
    [CID=00000000] JS:
                              ^
    [CID=00000000] JS:
    {TypeError: Cannot call method 'subst' of undefined
        at RouteProfile.isTellMeRoutable (unknown source)
        at RouteProfile.isRoutable (unknown source)
        at handle_request (unknown source)
    }
    */

    if (show_line && !message.IsEmpty())
    {
      // Print (filename):(line number): (message).
      String::Utf8Value filename(message->GetScriptResourceName());
      const char* filename_string = toCString(filename);
      int linenum = message->GetLineNumber();
      //fprintf(stderr, "%s:%i\n", filename_string, linenum);

      errorMsg << filename_string << ":" << linenum << std::endl;
      // Print line of source code.
      String::Utf8Value sourceline(message->GetSourceLine());
      const char* sourceline_string = toCString(sourceline);

      // HACK HACK HACK
      //
      // FIXME
      //
      // Because of how CommonJS modules work, all scripts are wrapped with a
      // "function (function (exports, __filename, ...) {"
      // to provide script local variables.
      //
      // When reporting errors on the first line of a script, this wrapper
      // function is leaked to the user. This HACK is to remove it. The length
      // of the wrapper is 62. That wrapper is defined in src/node.js
      //
      // If that wrapper is ever changed, then this number also has to be
      // updated. Or - someone could clean this up so that the two peices
      // don't need to be changed.
      //
      // Even better would be to get support into V8 for wrappers that
      // shouldn't be reported to users.
      int offset = linenum == 1 ? 62 : 0;

      //fprintf(stderr, "%s\n", sourceline_string + offset);
      errorMsg << sourceline_string + offset << std::endl;
      // Print wavy underline (GetUnderline is deprecated).
      int start = message->GetStartColumn();
      for (int i = offset; i < start; i++)
      {
        errorMsg << " ";
      }
      int end = message->GetEndColumn();
      for (int i = start; i < end; i++)
      {
        errorMsg << "^";
      }
      errorMsg << std::endl;
    }

    String::Utf8Value trace(try_catch.StackTrace());

    if (trace.length() > 0)
    {
      errorMsg << *trace;
    }
    OSS_LOG_ERROR("\t[CID=00000000] JS: " << *error << std::endl << "{" << std::endl << errorMsg.str() << std::endl << "}");
  }
}