зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1613705 - [localization] part6: Fine tune error reporting to only report to automation and nightly. r=platform-i18n-reviewers,dminor
Depends on D113248 Differential Revision: https://phabricator.services.mozilla.com/D113570
This commit is contained in:
Родитель
2537b79bfa
Коммит
589182cc2e
|
@ -16,6 +16,48 @@ using namespace mozilla::intl;
|
||||||
|
|
||||||
static const char* kObservedPrefs[] = {L10N_PSEUDO_PREF, nullptr};
|
static const char* kObservedPrefs[] = {L10N_PSEUDO_PREF, nullptr};
|
||||||
|
|
||||||
|
// The state where the application contains incomplete localization resources
|
||||||
|
// is much more common than for other types of core resources.
|
||||||
|
//
|
||||||
|
// In result, we our localization is designed to handle missing resources
|
||||||
|
// gracefully, and we need a more fine-tuned way to communicate those problems
|
||||||
|
// to developers.
|
||||||
|
//
|
||||||
|
// In particular, we want developers and early adopters to be able to reason
|
||||||
|
// about missing translations, without bothering end user in production, where
|
||||||
|
// the user cannot react to that.
|
||||||
|
//
|
||||||
|
// We currently differentiate between nightly/dev-edition builds or automation
|
||||||
|
// where we report the errors, and beta/release, where we silence them.
|
||||||
|
static bool MaybeReportErrorsToGecko(const nsTArray<nsCString>& aErrors,
|
||||||
|
ErrorResult& aRv,
|
||||||
|
nsIGlobalObject* global) {
|
||||||
|
if (!aErrors.IsEmpty()) {
|
||||||
|
if (xpc::IsInAutomation()) {
|
||||||
|
aRv.ThrowInvalidStateError(aErrors.ElementAt(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION) || defined(DEBUG)
|
||||||
|
Document* doc = nullptr;
|
||||||
|
if (global) {
|
||||||
|
nsPIDOMWindowInner* innerWindow = global->AsInnerWindow();
|
||||||
|
if (innerWindow) {
|
||||||
|
doc = innerWindow->GetExtantDoc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& error : aErrors) {
|
||||||
|
nsContentUtils::ReportToConsoleNonLocalized(NS_ConvertUTF8toUTF16(error),
|
||||||
|
nsIScriptError::warningFlag,
|
||||||
|
"l10n"_ns, doc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static nsTArray<ffi::L10nKey> ConvertFromL10nKeys(
|
static nsTArray<ffi::L10nKey> ConvertFromL10nKeys(
|
||||||
const Sequence<OwningUTF8StringOrL10nIdArgs>& aKeys) {
|
const Sequence<OwningUTF8StringOrL10nIdArgs>& aKeys) {
|
||||||
nsTArray<ffi::L10nKey> l10nKeys(aKeys.Length());
|
nsTArray<ffi::L10nKey> l10nKeys(aKeys.Length());
|
||||||
|
@ -235,9 +277,9 @@ already_AddRefed<Promise> Localization::FormatValue(
|
||||||
const nsTArray<nsCString>* aErrors) {
|
const nsTArray<nsCString>* aErrors) {
|
||||||
Promise* promise = const_cast<Promise*>(aPromise);
|
Promise* promise = const_cast<Promise*>(aPromise);
|
||||||
|
|
||||||
if (!aErrors->IsEmpty()) {
|
ErrorResult rv;
|
||||||
ErrorResult rv;
|
if (MaybeReportErrorsToGecko(*aErrors, rv,
|
||||||
rv.ThrowInvalidStateError(aErrors->ElementAt(0));
|
promise->GetParentObject())) {
|
||||||
promise->MaybeReject(std::move(rv));
|
promise->MaybeReject(std::move(rv));
|
||||||
} else {
|
} else {
|
||||||
promise->MaybeResolve(aValue);
|
promise->MaybeResolve(aValue);
|
||||||
|
@ -264,8 +306,10 @@ already_AddRefed<Promise> Localization::FormatValues(
|
||||||
const nsTArray<nsCString>* aErrors) {
|
const nsTArray<nsCString>* aErrors) {
|
||||||
Promise* promise = const_cast<Promise*>(aPromise);
|
Promise* promise = const_cast<Promise*>(aPromise);
|
||||||
|
|
||||||
if (!aErrors->IsEmpty()) {
|
ErrorResult rv;
|
||||||
promise->MaybeRejectWithInvalidStateError(aErrors->ElementAt(0));
|
if (MaybeReportErrorsToGecko(*aErrors, rv,
|
||||||
|
promise->GetParentObject())) {
|
||||||
|
promise->MaybeReject(std::move(rv));
|
||||||
} else {
|
} else {
|
||||||
promise->MaybeResolve(*aValues);
|
promise->MaybeResolve(*aValues);
|
||||||
}
|
}
|
||||||
|
@ -292,15 +336,14 @@ already_AddRefed<Promise> Localization::FormatMessages(
|
||||||
const nsTArray<nsCString>* aErrors) {
|
const nsTArray<nsCString>* aErrors) {
|
||||||
Promise* promise = const_cast<Promise*>(aPromise);
|
Promise* promise = const_cast<Promise*>(aPromise);
|
||||||
|
|
||||||
if (!aErrors->IsEmpty()) {
|
ErrorResult rv;
|
||||||
// XXX: We should consider throwing an array of errors here.
|
if (MaybeReportErrorsToGecko(*aErrors, rv,
|
||||||
promise->MaybeRejectWithInvalidStateError(aErrors->ElementAt(0));
|
promise->GetParentObject())) {
|
||||||
|
promise->MaybeReject(std::move(rv));
|
||||||
} else {
|
} else {
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
FallibleTArray<Nullable<L10nMessage>> messages;
|
FallibleTArray<Nullable<L10nMessage>> messages;
|
||||||
if (aRaw) {
|
messages = ConvertToL10nMessages(*aRaw, rv);
|
||||||
messages = ConvertToL10nMessages(*aRaw, rv);
|
|
||||||
}
|
|
||||||
if (rv.Failed()) {
|
if (rv.Failed()) {
|
||||||
promise->MaybeReject(std::move(rv));
|
promise->MaybeReject(std::move(rv));
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,11 +366,14 @@ void Localization::FormatValueSync(const nsACString& aId,
|
||||||
FluentBundle::ConvertArgs(args, l10nArgs);
|
FluentBundle::ConvertArgs(args, l10nArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi::localization_format_value_sync(mRaw.get(), &aId, &l10nArgs, &aRetVal,
|
bool rv = ffi::localization_format_value_sync(mRaw.get(), &aId, &l10nArgs,
|
||||||
&errors);
|
&aRetVal, &errors);
|
||||||
|
|
||||||
if (!errors.IsEmpty()) {
|
if (rv) {
|
||||||
aRv.ThrowInvalidStateError(errors.ElementAt(0));
|
MaybeReportErrorsToGecko(errors, aRv, GetParentObject());
|
||||||
|
} else {
|
||||||
|
aRv.ThrowInvalidStateError(
|
||||||
|
"Can't use formatValueSync when state is async.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,11 +400,14 @@ void Localization::FormatValuesSync(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi::localization_format_values_sync(mRaw.get(), &l10nKeys, &aRetVal,
|
bool rv = ffi::localization_format_values_sync(mRaw.get(), &l10nKeys,
|
||||||
&errors);
|
&aRetVal, &errors);
|
||||||
|
|
||||||
if (!errors.IsEmpty()) {
|
if (rv) {
|
||||||
aRv.ThrowInvalidStateError(errors.ElementAt(0));
|
MaybeReportErrorsToGecko(errors, aRv, GetParentObject());
|
||||||
|
} else {
|
||||||
|
aRv.ThrowInvalidStateError(
|
||||||
|
"Can't use formatValuesSync when state is async.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,11 +436,17 @@ void Localization::FormatMessagesSync(
|
||||||
|
|
||||||
nsTArray<ffi::OptionalL10nMessage> result(l10nKeys.Length());
|
nsTArray<ffi::OptionalL10nMessage> result(l10nKeys.Length());
|
||||||
|
|
||||||
ffi::localization_format_messages_sync(mRaw.get(), &l10nKeys, &result,
|
bool rv = ffi::localization_format_messages_sync(mRaw.get(), &l10nKeys,
|
||||||
&errors);
|
&result, &errors);
|
||||||
|
|
||||||
if (!errors.IsEmpty()) {
|
if (rv) {
|
||||||
aRv.ThrowInvalidStateError(errors.ElementAt(0));
|
MaybeReportErrorsToGecko(errors, aRv, GetParentObject());
|
||||||
|
if (!aRv.Failed()) {
|
||||||
|
aRetVal = ConvertToL10nMessages(result, aRv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aRv.ThrowInvalidStateError(
|
||||||
|
"Can't use formatMessagesSync when state is async.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче