Bug 1900706 - Expose equivalent of nsContentUtils::ReportToConsole on nsIGlobalObject. r=smaug

A notable change in this stack is to ensure that we populate mOwner on
workers.

Differential Revision: https://phabricator.services.mozilla.com/D213724
This commit is contained in:
Andrew Sutherland 2024-10-24 03:02:39 +00:00
Родитель 1242518a9b
Коммит 78936f73aa
11 изменённых файлов: 145 добавлений и 63 удалений

Просмотреть файл

@ -1685,6 +1685,15 @@ mozilla::dom::StorageManager* nsGlobalWindowInner::GetStorageManager() {
// * a Window object whose associated Document is fully active
bool nsGlobalWindowInner::IsEligibleForMessaging() { return IsFullyActive(); }
void nsGlobalWindowInner::ReportToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) {
nsContentUtils::ReportToConsole(aErrorFlags, aCategory, mDoc, aFile,
aMessageName.get(), aParams, aLocation);
}
nsresult nsGlobalWindowInner::EnsureScriptEnvironment() {
// NOTE: We can't use FORWARD_TO_OUTER here because we don't want to fail if
// we're called on an inactive inner window.

Просмотреть файл

@ -258,6 +258,12 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
bool IsEligibleForMessaging() override;
void ReportToConsole(uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile,
const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) override;
void TraceGlobalJSObject(JSTracer* aTrc);
virtual nsresult EnsureScriptEnvironment() override;

Просмотреть файл

@ -494,3 +494,15 @@ bool nsIGlobalObject::ShouldResistFingerprinting(CallerType aCallerType,
return aCallerType != CallerType::System &&
ShouldResistFingerprinting(aTarget);
}
void nsIGlobalObject::ReportToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) {
// We pass nullptr for the document because nsGlobalWindowInner handles the
// case where it should be non-null. We also expect the worker impl to
// override.
nsContentUtils::ReportToConsole(aErrorFlags, aCategory, nullptr, aFile,
aMessageName.get(), aParams, aLocation);
}

Просмотреть файл

@ -315,6 +315,41 @@ class nsIGlobalObject : public nsISupports {
virtual bool IsXPCSandbox() { return false; }
/**
* Report a localized error message to the error console. Currently this
* amounts to a wrapper around nsContentUtils::ReportToConsole for window
* globals and a runnable bounced to the main thread to call
* nsContentUtils::ReportToConsole for workers but the intent is to migrate
* towards logging the messages to the `dom::Console` for the global. See
* bug 1900706 for more context.
*
* This method returns void because there is no reasonable action for a caller
* for dynamic failure and we can assert on things like erroneous message
* names.
*
* @param aErrorFlags See nsIScriptError.
* @param aCategory Name of module reporting error.
* @param aFile Properties file containing localized message.
* @param aMessageName Name of localized message.
* @param [aParams=empty-array] (Optional) Parameters to be substituted into
* localized message.
* @param [aURI=nullptr] (Optional) URI of resource containing error; if
* omitted, an attempt will be made to use the URI associated with
* the global (ex: the document URI).
* @param [aSourceLine=u""_ns] (Optional) The text of the line that
* contains the error (may be empty).
* @param [aLineNumber=0] (Optional) Line number within resource
* containing error.
* @param [aColumnNumber=0] (Optional) Column number within resource
* containing error.
*/
virtual void ReportToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams = nsTArray<nsString>(),
const mozilla::SourceLocation& aLocation =
mozilla::JSCallingLocation::Get());
protected:
virtual ~nsIGlobalObject();

Просмотреть файл

@ -46,12 +46,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceObserver)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
const char UnsupportedEntryTypesIgnoredMsgId[] = "UnsupportedEntryTypesIgnored";
const char AllEntryTypesIgnoredMsgId[] = "AllEntryTypesIgnored";
PerformanceObserver::PerformanceObserver(nsPIDOMWindowInner* aOwner,
PerformanceObserverCallback& aCb)
: mOwner(aOwner),
: mOwner(aOwner->AsGlobal()),
mCallback(&aCb),
mObserverType(ObserverTypeUndefined),
mConnected(false) {
@ -61,8 +58,11 @@ PerformanceObserver::PerformanceObserver(nsPIDOMWindowInner* aOwner,
PerformanceObserver::PerformanceObserver(WorkerPrivate* aWorkerPrivate,
PerformanceObserverCallback& aCb)
: mCallback(&aCb), mObserverType(ObserverTypeUndefined), mConnected(false) {
MOZ_ASSERT(aWorkerPrivate);
: mOwner(aWorkerPrivate->GlobalScope()),
mCallback(&aCb),
mObserverType(ObserverTypeUndefined),
mConnected(false) {
MOZ_ASSERT(aWorkerPrivate->GlobalScope());
mPerformance = aWorkerPrivate->GlobalScope()->GetPerformance();
}
@ -137,29 +137,13 @@ static constexpr nsLiteralString kValidTypeNames[5] = {
u"mark"_ns, u"measure"_ns, u"navigation"_ns, u"paint"_ns, u"resource"_ns,
};
void PerformanceObserver::ReportUnsupportedTypesErrorToConsole(
bool aIsMainThread, const char* msgId, const nsString& aInvalidTypes) {
if (!aIsMainThread) {
nsTArray<nsString> params;
params.AppendElement(aInvalidTypes);
WorkerPrivate::ReportErrorToConsole(msgId, params);
} else {
nsCOMPtr<nsPIDOMWindowInner> ownerWindow = do_QueryInterface(mOwner);
Document* document = ownerWindow->GetExtantDoc();
AutoTArray<nsString, 1> params = {aInvalidTypes};
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns,
document, nsContentUtils::eDOM_PROPERTIES,
msgId, params);
}
}
void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
ErrorResult& aRv) {
const Optional<Sequence<nsString>>& maybeEntryTypes = aOptions.mEntryTypes;
const Optional<nsString>& maybeType = aOptions.mType;
const Optional<bool>& maybeBuffered = aOptions.mBuffered;
if (!mPerformance) {
if (!mPerformance || !mOwner) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
@ -241,16 +225,18 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
}
if (!invalidTypesJoined.IsEmpty()) {
ReportUnsupportedTypesErrorToConsole(NS_IsMainThread(),
UnsupportedEntryTypesIgnoredMsgId,
invalidTypesJoined);
AutoTArray<nsString, 1> params = {invalidTypesJoined};
mOwner->ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns,
nsContentUtils::eDOM_PROPERTIES,
"UnsupportedEntryTypesIgnored"_ns, params);
// (we don't return because we're ignoring and we keep going)
}
/* 3.3.1.5.3 */
if (validEntryTypes.IsEmpty()) {
nsString errorString;
ReportUnsupportedTypesErrorToConsole(
NS_IsMainThread(), AllEntryTypesIgnoredMsgId, errorString);
mOwner->ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns,
nsContentUtils::eDOM_PROPERTIES,
"AllEntryTypesIgnored"_ns);
return;
}
@ -289,8 +275,10 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
}
if (!typeValid) {
ReportUnsupportedTypesErrorToConsole(
NS_IsMainThread(), UnsupportedEntryTypesIgnoredMsgId, type);
AutoTArray<nsString, 1> params = {type};
mOwner->ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns,
nsContentUtils::eDOM_PROPERTIES,
"UnsupportedEntryTypesIgnored"_ns, params);
return;
}

Просмотреть файл

@ -63,12 +63,9 @@ class PerformanceObserver final : public nsISupports, public nsWrapperCache {
bool ObservesTypeOfEntry(PerformanceEntry* aEntry);
private:
void ReportUnsupportedTypesErrorToConsole(bool aIsMainThread,
const char* msgId,
const nsString& aInvalidTypes);
~PerformanceObserver();
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIGlobalObject> mOwner;
RefPtr<PerformanceObserverCallback> mCallback;
RefPtr<Performance> mPerformance;
nsTArray<nsString> mEntryTypes;

Просмотреть файл

@ -1154,7 +1154,9 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) {
// Worker spawn gets queued due to hitting max workers per domain
// limit so let's log a warning.
WorkerPrivate::ReportErrorToConsole("HittingMaxWorkersPerDomain2");
WorkerPrivate::ReportErrorToConsole(nsIScriptError::warningFlag, "DOM"_ns,
nsContentUtils::eDOM_PROPERTIES,
"HittingMaxWorkersPerDomain2"_ns);
if (isServiceWorker) {
Telemetry::Accumulate(Telemetry::SERVICE_WORKER_SPAWN_GETS_QUEUED, 1);

Просмотреть файл

@ -550,13 +550,14 @@ class PropagateStorageAccessPermissionGrantedRunnable final
};
class ReportErrorToConsoleRunnable final : public WorkerParentThreadRunnable {
const char* mMessage;
const nsTArray<nsString> mParams;
public:
// aWorkerPrivate is the worker thread we're on (or the main thread, if null)
static void Report(WorkerPrivate* aWorkerPrivate, const char* aMessage,
const nsTArray<nsString>& aParams) {
static void Report(WorkerPrivate* aWorkerPrivate, uint32_t aErrorFlags,
const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile,
const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) {
if (aWorkerPrivate) {
aWorkerPrivate->AssertIsOnWorkerThread();
} else {
@ -566,24 +567,32 @@ class ReportErrorToConsoleRunnable final : public WorkerParentThreadRunnable {
// Now fire a runnable to do the same on the parent's thread if we can.
if (aWorkerPrivate) {
RefPtr<ReportErrorToConsoleRunnable> runnable =
new ReportErrorToConsoleRunnable(aWorkerPrivate, aMessage, aParams);
new ReportErrorToConsoleRunnable(aWorkerPrivate, aErrorFlags,
aCategory, aFile, aMessageName,
aParams, aLocation);
runnable->Dispatch(aWorkerPrivate);
return;
}
// Log a warning to the console.
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns,
nullptr, nsContentUtils::eDOM_PROPERTIES,
aMessage, aParams);
nsContentUtils::ReportToConsole(aErrorFlags, aCategory, nullptr, aFile,
aMessageName.get(), aParams, aLocation);
}
private:
ReportErrorToConsoleRunnable(WorkerPrivate* aWorkerPrivate,
const char* aMessage,
const nsTArray<nsString>& aParams)
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile,
const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation)
: WorkerParentThreadRunnable("ReportErrorToConsoleRunnable"),
mMessage(aMessage),
mParams(aParams.Clone()) {}
mErrorFlags(aErrorFlags),
mCategory(aCategory),
mFile(aFile),
mMessageName(aMessageName),
mParams(aParams.Clone()),
mLocation(aLocation) {}
virtual void PostDispatch(WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) override {
@ -597,9 +606,17 @@ class ReportErrorToConsoleRunnable final : public WorkerParentThreadRunnable {
WorkerPrivate* aWorkerPrivate) override {
WorkerPrivate* parent = aWorkerPrivate->GetParent();
MOZ_ASSERT_IF(!parent, NS_IsMainThread());
Report(parent, mMessage, mParams);
Report(parent, mErrorFlags, mCategory, mFile, mMessageName, mParams,
mLocation);
return true;
}
const uint32_t mErrorFlags;
const nsCString mCategory;
const nsContentUtils::PropertiesFile mFile;
const nsCString mMessageName;
const nsTArray<nsString> mParams;
const mozilla::SourceLocation mLocation;
};
class RunExpiredTimoutsRunnable final : public WorkerThreadRunnable,
@ -5398,20 +5415,18 @@ void WorkerPrivate::ReportError(JSContext* aCx,
}
// static
void WorkerPrivate::ReportErrorToConsole(const char* aMessage) {
nsTArray<nsString> emptyParams;
WorkerPrivate::ReportErrorToConsole(aMessage, emptyParams);
}
// static
void WorkerPrivate::ReportErrorToConsole(const char* aMessage,
const nsTArray<nsString>& aParams) {
void WorkerPrivate::ReportErrorToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) {
WorkerPrivate* wp = nullptr;
if (!NS_IsMainThread()) {
wp = GetCurrentThreadWorkerPrivate();
}
ReportErrorToConsoleRunnable::Report(wp, aMessage, aParams);
ReportErrorToConsoleRunnable::Report(wp, aErrorFlags, aCategory, aFile,
aMessageName, aParams, aLocation);
}
int32_t WorkerPrivate::SetTimeout(JSContext* aCx, TimeoutHandler* aHandler,

Просмотреть файл

@ -415,10 +415,12 @@ class WorkerPrivate final
void ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
JSErrorReport* aReport);
static void ReportErrorToConsole(const char* aMessage);
static void ReportErrorToConsole(const char* aMessage,
const nsTArray<nsString>& aParams);
static void ReportErrorToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams = nsTArray<nsString>(),
const mozilla::SourceLocation& aLocation =
mozilla::JSCallingLocation::Get());
int32_t SetTimeout(JSContext* aCx, TimeoutHandler* aHandler, int32_t aTimeout,
bool aIsInterval, Timeout::Reason aReason,

Просмотреть файл

@ -915,6 +915,16 @@ mozilla::dom::StorageManager* WorkerGlobalScope::GetStorageManager() {
bool WorkerGlobalScope::IsEligibleForMessaging() {
return mIsEligibleForMessaging;
}
void WorkerGlobalScope::ReportToConsole(
uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) {
WorkerPrivate::ReportErrorToConsole(aErrorFlags, aCategory, aFile,
aMessageName, aParams, aLocation);
}
void WorkerGlobalScope::StorageAccessPermissionGranted() {
// Reset the IndexedDB factory.
mIndexedDB = nullptr;

Просмотреть файл

@ -260,6 +260,12 @@ class WorkerGlobalScope : public WorkerGlobalScopeBase {
bool IsEligibleForMessaging() final;
void ReportToConsole(uint32_t aErrorFlags, const nsCString& aCategory,
nsContentUtils::PropertiesFile aFile,
const nsCString& aMessageName,
const nsTArray<nsString>& aParams,
const mozilla::SourceLocation& aLocation) final;
// WorkerGlobalScope WebIDL implementation
WorkerGlobalScope* Self() { return this; }