зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1217909 P1 Report service worker exceptions to controlled documents. r=catalinb
* * * Bug 1217909 P1 interdiff 001 refactor
This commit is contained in:
Родитель
2a23ba2a31
Коммит
c311fd953d
|
@ -2399,14 +2399,53 @@ ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration)
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
ServiceWorkerManager::ReportToAllClients(const nsCString& aScope,
|
||||
const nsString& aMessage,
|
||||
const nsString& aFilename,
|
||||
const nsString& aLine,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aFilename);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Report errors to the consoles of every controlled document
|
||||
for (auto iter = mControlledDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerRegistrationInfo* reg = iter.UserData();
|
||||
MOZ_ASSERT(reg);
|
||||
if (!reg->mScope.Equals(aScope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(iter.Key());
|
||||
if (!doc || !doc->GetWindow()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsContentUtils::ReportToConsoleNonLocalized(aMessage,
|
||||
aFlags,
|
||||
NS_LITERAL_CSTRING("Service Workers"),
|
||||
doc,
|
||||
uri,
|
||||
aLine,
|
||||
aLineNumber,
|
||||
aColumnNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::HandleError(JSContext* aCx,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsCString& aScope,
|
||||
const nsString& aWorkerURL,
|
||||
nsString aMessage,
|
||||
nsString aFilename,
|
||||
nsString aLine,
|
||||
const nsString& aMessage,
|
||||
const nsString& aFilename,
|
||||
const nsString& aLine,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
uint32_t aFlags,
|
||||
|
@ -2414,46 +2453,47 @@ ServiceWorkerManager::HandleError(JSContext* aCx,
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(!JSREPORT_IS_WARNING(aFlags));
|
||||
|
||||
nsAutoCString scopeKey;
|
||||
nsresult rv = PrincipalToScopeKey(aPrincipal, scopeKey);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerManager::RegistrationDataPerPrincipal* data;
|
||||
if (!mRegistrationInfos.Get(scopeKey, &data)) {
|
||||
return false;
|
||||
if (NS_WARN_IF(!mRegistrationInfos.Get(scopeKey, &data))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data->mSetOfScopesBeingUpdated.Contains(aScope)) {
|
||||
return false;
|
||||
// If this is a failure, we may need to cancel an in-progress registration.
|
||||
if (!JSREPORT_IS_WARNING(aFlags)) {
|
||||
ServiceWorkerJob* job = nullptr;
|
||||
|
||||
if (data->mSetOfScopesBeingUpdated.Contains(aScope)) {
|
||||
data->mSetOfScopesBeingUpdated.Remove(aScope);
|
||||
|
||||
ServiceWorkerJobQueue* queue = data->mJobQueues.Get(aScope);
|
||||
MOZ_ASSERT(queue);
|
||||
job = queue->Peek();
|
||||
}
|
||||
|
||||
if (job) {
|
||||
MOZ_ASSERT(job->IsRegisterJob());
|
||||
RefPtr<ServiceWorkerRegisterJob> regJob =
|
||||
static_cast<ServiceWorkerRegisterJob*>(job);
|
||||
|
||||
RootedDictionary<ErrorEventInit> init(aCx);
|
||||
init.mMessage = aMessage;
|
||||
init.mFilename = aFilename;
|
||||
init.mLineno = aLineNumber;
|
||||
init.mColno = aColumnNumber;
|
||||
|
||||
regJob->Fail(aExnType, init);
|
||||
}
|
||||
}
|
||||
|
||||
data->mSetOfScopesBeingUpdated.Remove(aScope);
|
||||
|
||||
ServiceWorkerJobQueue* queue = data->mJobQueues.Get(aScope);
|
||||
MOZ_ASSERT(queue);
|
||||
ServiceWorkerJob* job = queue->Peek();
|
||||
if (job) {
|
||||
MOZ_ASSERT(job->IsRegisterJob());
|
||||
RefPtr<ServiceWorkerRegisterJob> regJob = static_cast<ServiceWorkerRegisterJob*>(job);
|
||||
|
||||
RootedDictionary<ErrorEventInit> init(aCx);
|
||||
init.mMessage = aMessage;
|
||||
init.mFilename = aFilename;
|
||||
init.mLineno = aLineNumber;
|
||||
init.mColno = aColumnNumber;
|
||||
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"Script error caused ServiceWorker registration to fail: %s:%u '%s'",
|
||||
NS_ConvertUTF16toUTF8(aFilename).get(), aLineNumber,
|
||||
NS_ConvertUTF16toUTF8(aMessage).get()).get());
|
||||
regJob->Fail(aExnType, init);
|
||||
}
|
||||
|
||||
return true;
|
||||
ReportToAllClients(aScope, aMessage, aFilename, aLine, aLineNumber,
|
||||
aColumnNumber, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -389,16 +389,25 @@ public:
|
|||
void
|
||||
FinishFetch(ServiceWorkerRegistrationInfo* aRegistration);
|
||||
|
||||
// Returns true if the error was handled, false if normal worker error
|
||||
// handling should continue.
|
||||
bool
|
||||
void
|
||||
ReportToAllClients(const nsCString& aScope,
|
||||
const nsString& aMessage,
|
||||
const nsString& aFilename,
|
||||
const nsString& aLine,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
uint32_t aFlags);
|
||||
|
||||
// Always consumes the error by reporting to consoles of all controlled
|
||||
// documents.
|
||||
void
|
||||
HandleError(JSContext* aCx,
|
||||
nsIPrincipal* aPrincipal,
|
||||
const nsCString& aScope,
|
||||
const nsString& aWorkerURL,
|
||||
nsString aMessage,
|
||||
nsString aFilename,
|
||||
nsString aLine,
|
||||
const nsString& aMessage,
|
||||
const nsString& aFilename,
|
||||
const nsString& aLine,
|
||||
uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber,
|
||||
uint32_t aFlags,
|
||||
|
|
|
@ -1173,6 +1173,10 @@ private:
|
|||
event->ReportCanceled();
|
||||
runnable = new CancelChannelRunnable(mInterceptedChannel,
|
||||
NS_ERROR_INTERCEPTION_FAILED);
|
||||
} else if (event->GetInternalNSEvent()->mFlags.mExceptionHasBeenRisen) {
|
||||
// Exception logged via the WorkerPrivate ErrorReporter
|
||||
runnable = new CancelChannelRunnable(mInterceptedChannel,
|
||||
NS_ERROR_INTERCEPTION_FAILED);
|
||||
} else {
|
||||
runnable = new ResumeRequest(mInterceptedChannel);
|
||||
}
|
||||
|
|
|
@ -1070,27 +1070,28 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsServiceWorker() || aWorkerPrivate->IsSharedWorker()) {
|
||||
if (aWorkerPrivate->IsServiceWorker() && !JSREPORT_IS_WARNING(mFlags)) {
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
bool handled = swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
|
||||
aWorkerPrivate->WorkerName(),
|
||||
aWorkerPrivate->ScriptURL(),
|
||||
mMessage,
|
||||
mFilename, mLine, mLineNumber,
|
||||
mColumnNumber, mFlags, mExnType);
|
||||
if (handled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsSharedWorker()) {
|
||||
aWorkerPrivate->BroadcastErrorToSharedWorkers(aCx, mMessage, mFilename,
|
||||
mLine, mLineNumber,
|
||||
mColumnNumber, mFlags);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Service workers do not have a main thread parent global, so normal
|
||||
// worker error reporting will crash. Instead, pass the error to
|
||||
// the ServiceWorkerManager to report on any controlled documents.
|
||||
if (aWorkerPrivate->IsServiceWorker()) {
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
MOZ_ASSERT(swm);
|
||||
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
|
||||
aWorkerPrivate->WorkerName(),
|
||||
aWorkerPrivate->ScriptURL(),
|
||||
mMessage,
|
||||
mFilename, mLine, mLineNumber,
|
||||
mColumnNumber, mFlags, mExnType);
|
||||
return true;
|
||||
}
|
||||
|
||||
// The innerWindowId is only required if we are going to ReportError
|
||||
// below, which is gated on this condition. The inner window correctness
|
||||
// check is only going to succeed when the worker is accepting events.
|
||||
|
|
Загрузка…
Ссылка в новой задаче