v8::Local<v8::Value> V8ErrorHandler::callListenerFunction( ScriptState* scriptState, v8::Local<v8::Value> jsEvent, Event* event) { ASSERT(!jsEvent.IsEmpty()); if (!event->hasInterface(EventNames::ErrorEvent)) return V8EventListener::callListenerFunction(scriptState, jsEvent, event); ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event); if (errorEvent->world() && errorEvent->world() != &world()) return v8::Null(isolate()); v8::Local<v8::Object> listener = getListenerObject(scriptState->getExecutionContext()); if (listener.IsEmpty() || !listener->IsFunction()) return v8::Null(isolate()); v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener); v8::Local<v8::Object> thisValue = scriptState->context()->Global(); v8::Local<v8::Object> eventObject; if (!jsEvent->ToObject(scriptState->context()).ToLocal(&eventObject)) return v8::Null(isolate()); auto privateError = V8PrivateProperty::getErrorEventError(isolate()); v8::Local<v8::Value> error = privateError.getOrUndefined(scriptState->context(), eventObject); if (error->IsUndefined()) error = v8::Null(isolate()); v8::Local<v8::Value> parameters[5] = { v8String(isolate(), errorEvent->message()), v8String(isolate(), errorEvent->filename()), v8::Integer::New(isolate(), errorEvent->lineno()), v8::Integer::New(isolate(), errorEvent->colno()), error}; v8::TryCatch tryCatch(isolate()); tryCatch.SetVerbose(true); v8::MaybeLocal<v8::Value> result; if (scriptState->getExecutionContext()->isWorkerGlobalScope()) { result = V8ScriptRunner::callFunction( callFunction, scriptState->getExecutionContext(), thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate()); } else { result = V8ScriptRunner::callFunction( callFunction, scriptState->getExecutionContext(), thisValue, WTF_ARRAY_LENGTH(parameters), parameters, isolate()); } v8::Local<v8::Value> returnValue; if (!result.ToLocal(&returnValue)) return v8::Null(isolate()); return returnValue; }
static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises& rejectedPromises, ScriptState* scriptState) { if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { rejectedPromises.handlerAdded(data); return; } ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); v8::Local<v8::Promise> promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); ExecutionContext* context = scriptState->getExecutionContext(); v8::Local<v8::Value> exception = data.GetValue(); if (V8DOMWrapper::isWrapper(isolate, exception)) { // Try to get the stack & location from a wrapped exception object (e.g. // DOMException). ASSERT(exception->IsObject()); auto privateError = V8PrivateProperty::getDOMExceptionError(isolate); v8::Local<v8::Value> error = privateError.getOrUndefined( scriptState->context(), exception.As<v8::Object>()); if (!error->IsUndefined()) exception = error; } String errorMessage; AccessControlStatus corsStatus = NotSharableCrossOrigin; std::unique_ptr<SourceLocation> location; v8::Local<v8::Message> message = v8::Exception::CreateMessage(isolate, exception); if (!message.IsEmpty()) { // message->Get() can be empty here. https://crbug.com/450330 errorMessage = toCoreStringWithNullCheck(message->Get()); location = SourceLocation::fromMessage(isolate, message, context); if (message->IsSharedCrossOrigin()) corsStatus = SharableCrossOrigin; } else { location = SourceLocation::create(context->url().getString(), 0, 0, nullptr); } String messageForConsole = extractMessageForConsole(isolate, data.GetValue()); if (!messageForConsole.isEmpty()) errorMessage = "Uncaught " + messageForConsole; rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, std::move(location), corsStatus); }
// static v8::Local<v8::Value> V8ErrorHandler::loadExceptionFromErrorEventWrapper( ScriptState* scriptState, ErrorEvent* event, v8::Local<v8::Object> creationContext) { v8::Local<v8::Value> wrappedEvent = toV8(event, creationContext, scriptState->isolate()); if (wrappedEvent.IsEmpty() || !wrappedEvent->IsObject()) return v8::Local<v8::Value>(); DCHECK(wrappedEvent->IsObject()); auto privateError = V8PrivateProperty::getErrorEventError(scriptState->isolate()); v8::Local<v8::Value> error = privateError.getOrUndefined( scriptState->context(), wrappedEvent.As<v8::Object>()); if (error->IsUndefined()) return v8::Local<v8::Value>(); return error; }