Replace newTranslatableError with UserFriendlyError (#10440

* Introduce UserFriendlyError

* Replace newTranslatableError with UserFriendlyError

* Remove ITranslatableError

* Fix up some strict lints

* Document when we/why we can remove

* Update matrix-web-i18n

Includes changes to find `new UserFriendlyError`,
see https://github.com/matrix-org/matrix-web-i18n/pull/6

* Include room ID in error

* Translate fallback error

* Translate better

* Update i18n strings

* Better re-use

* Minor comment fixes
This commit is contained in:
Eric Eastwood 2023-03-31 02:30:43 -05:00 committed by GitHub
parent 567248d5c5
commit ff1468b6d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 285 additions and 99 deletions

View file

@ -21,8 +21,25 @@ import {
ICustomTranslations,
registerCustomTranslations,
setLanguage,
UserFriendlyError,
} from "../src/languageHandler";
async function setupTranslationOverridesForTests(overrides: ICustomTranslations) {
const lookupUrl = "/translations.json";
const fn = (url: string): ICustomTranslations => {
expect(url).toEqual(lookupUrl);
return overrides;
};
SdkConfig.add({
custom_translations_url: lookupUrl,
});
CustomTranslationOptions.lookupFn = fn;
await registerCustomTranslations({
testOnlyIgnoreCustomTranslationsCache: true,
});
}
describe("languageHandler", () => {
afterEach(() => {
SdkConfig.unset();
@ -33,38 +50,72 @@ describe("languageHandler", () => {
const str = "This is a test string that does not exist in the app.";
const enOverride = "This is the English version of a custom string.";
const deOverride = "This is the German version of a custom string.";
const overrides: ICustomTranslations = {
// First test that overrides aren't being used
await setLanguage("en");
expect(_t(str)).toEqual(str);
await setLanguage("de");
expect(_t(str)).toEqual(str);
await setupTranslationOverridesForTests({
[str]: {
en: enOverride,
de: deOverride,
},
};
const lookupUrl = "/translations.json";
const fn = (url: string): ICustomTranslations => {
expect(url).toEqual(lookupUrl);
return overrides;
};
// First test that overrides aren't being used
await setLanguage("en");
expect(_t(str)).toEqual(str);
await setLanguage("de");
expect(_t(str)).toEqual(str);
});
// Now test that they *are* being used
SdkConfig.add({
custom_translations_url: lookupUrl,
});
CustomTranslationOptions.lookupFn = fn;
await registerCustomTranslations();
await setLanguage("en");
expect(_t(str)).toEqual(enOverride);
await setLanguage("de");
expect(_t(str)).toEqual(deOverride);
});
describe("UserFriendlyError", () => {
const testErrorMessage = "This email address is already in use (%(email)s)";
beforeEach(async () => {
// Setup some strings with variable substituations that we can use in the tests.
const deOverride = "Diese E-Mail-Adresse wird bereits verwendet (%(email)s)";
await setupTranslationOverridesForTests({
[testErrorMessage]: {
en: testErrorMessage,
de: deOverride,
},
});
});
it("includes English message and localized translated message", async () => {
await setLanguage("de");
const friendlyError = new UserFriendlyError(testErrorMessage, {
email: "test@example.com",
cause: undefined,
});
// Ensure message is in English so it's readable in the logs
expect(friendlyError.message).toStrictEqual("This email address is already in use (test@example.com)");
// Ensure the translated message is localized appropriately
expect(friendlyError.translatedMessage).toStrictEqual(
"Diese E-Mail-Adresse wird bereits verwendet (test@example.com)",
);
});
it("includes underlying cause error", async () => {
await setLanguage("de");
const underlyingError = new Error("Fake underlying error");
const friendlyError = new UserFriendlyError(testErrorMessage, {
email: "test@example.com",
cause: underlyingError,
});
expect(friendlyError.cause).toStrictEqual(underlyingError);
});
it("ok to omit the substitution variables and cause object, there just won't be any cause", async () => {
const friendlyError = new UserFriendlyError("foo error");
expect(friendlyError.cause).toBeUndefined();
});
});
});