static void messageHandlerInWorker(v8::Local<v8::Message> message, v8::Local<v8::Value> data)
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    V8PerIsolateData* perIsolateData = V8PerIsolateData::from(isolate);

    // During the frame teardown, there may not be a valid context.
    ScriptState* scriptState = ScriptState::current(isolate);
    if (!scriptState->contextIsValid())
        return;

    // Exceptions that occur in error handler should be ignored since in that case
    // WorkerGlobalScope::reportException will send the exception to the worker object.
    if (perIsolateData->isReportingException())
        return;

    perIsolateData->setReportingException(true);

    ExecutionContext* context = scriptState->getExecutionContext();
    std::unique_ptr<SourceLocation> location = SourceLocation::fromMessage(isolate, message, context);
    ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Get()), std::move(location), &scriptState->world());

    AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCrossOrigin : NotSharableCrossOrigin;

    // If execution termination has been triggered as part of constructing
    // the error event from the v8::Message, quietly leave.
    if (!isolate->IsExecutionTerminating()) {
        V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, data, scriptState->context()->Global());
        scriptState->getExecutionContext()->reportException(event, corsStatus);
    }

    perIsolateData->setReportingException(false);
}
Beispiel #2
0
static void messageHandlerInMainThread(v8::Local<v8::Message> message,
                                       v8::Local<v8::Value> data) {
  ASSERT(isMainThread());
  v8::Isolate* isolate = v8::Isolate::GetCurrent();

  if (isolate->GetEnteredContext().IsEmpty())
    return;

  // If called during context initialization, there will be no entered context.
  ScriptState* scriptState = ScriptState::current(isolate);
  if (!scriptState->contextIsValid())
    return;

  ExecutionContext* context = scriptState->getExecutionContext();
  std::unique_ptr<SourceLocation> location =
      SourceLocation::fromMessage(isolate, message, context);

  AccessControlStatus accessControlStatus = NotSharableCrossOrigin;
  if (message->IsOpaque())
    accessControlStatus = OpaqueResource;
  else if (message->IsSharedCrossOrigin())
    accessControlStatus = SharableCrossOrigin;

  ErrorEvent* event =
      ErrorEvent::create(toCoreStringWithNullCheck(message->Get()),
                         std::move(location), &scriptState->world());

  String messageForConsole = extractMessageForConsole(isolate, data);
  if (!messageForConsole.isEmpty())
    event->setUnsanitizedMessage("Uncaught " + messageForConsole);

  // This method might be called while we're creating a new context. In this
  // case, we avoid storing the exception object, as we can't create a wrapper
  // during context creation.
  // FIXME: Can we even get here during initialization now that we bail out when
  // GetEntered returns an empty handle?
  if (context->isDocument()) {
    LocalFrame* frame = toDocument(context)->frame();
    if (frame && frame->script().existingWindowProxy(scriptState->world())) {
      V8ErrorHandler::storeExceptionOnErrorEventWrapper(
          scriptState, event, data, scriptState->context()->Global());
    }
  }

  if (scriptState->world().isPrivateScriptIsolatedWorld()) {
    // We allow a private script to dispatch error events even in a
    // EventDispatchForbiddenScope scope.  Without having this ability, it's
    // hard to debug the private script because syntax errors in the private
    // script are not reported to console (the private script just crashes
    // silently).  Allowing error events in private scripts is safe because
    // error events don't propagate to other isolated worlds (which means that
    // the error events won't fire any event listeners in user's scripts).
    EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents;
    context->dispatchErrorEvent(event, accessControlStatus);
  } else {
    context->dispatchErrorEvent(event, accessControlStatus);
  }
}
static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
{
    v8::Local<v8::Promise> promise = data.GetPromise();

    // Bail out if called during context initialization.
    v8::Isolate* isolate = promise->GetIsolate();
    ScriptState* scriptState = ScriptState::current(isolate);
    if (!scriptState->contextIsValid())
        return;

    ExecutionContext* executionContext = scriptState->getExecutionContext();
    if (!executionContext)
        return;

    ASSERT(executionContext->isWorkerGlobalScope());
    WorkerOrWorkletScriptController* scriptController = toWorkerGlobalScope(executionContext)->scriptController();
    ASSERT(scriptController);

    promiseRejectHandler(data, *scriptController->getRejectedPromises(), scriptState);
}