mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
Fix translation error loop (#10636)
* Test issue duplicates and fix translation error loop Signed-off-by: Artem Savchenko <armisav@gmail.com> * Clean up Signed-off-by: Artem Savchenko <armisav@gmail.com> --------- Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -78,7 +78,8 @@ export const Analytics = {
|
||||
|
||||
addEventListener(PlatformEvent, async (_event, _status: Status) => {
|
||||
if (_status.severity === Severity.ERROR) {
|
||||
const label = await translate(_status.code, _status.params, 'en')
|
||||
// Skip error broadcast in translate to avoid infinite loop
|
||||
const label = await translate(_status.code, _status.params, 'en', true)
|
||||
Analytics.handleError(new Error(label))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -88,7 +88,16 @@ async function createClient (
|
||||
config: ServerConfig,
|
||||
options: ConnectOptions
|
||||
): Promise<PlatformClient> {
|
||||
addLocation(clientId, () => import(/* webpackChunkName: "client" */ '@hcengineering/client-resources'))
|
||||
addLocation(clientId, () => {
|
||||
// In Node/Jest environments, dynamic import callbacks can fail without
|
||||
// --experimental-vm-modules. Use require there and keep dynamic import
|
||||
// for browser/bundler environments.
|
||||
if (typeof window === 'undefined') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
return Promise.resolve(require('@hcengineering/client-resources'))
|
||||
}
|
||||
return import(/* webpackChunkName: "client" */ '@hcengineering/client-resources')
|
||||
})
|
||||
|
||||
const { socketFactory, connectionTimeout } = options
|
||||
|
||||
|
||||
@@ -64,11 +64,21 @@ export async function loadPluginStrings (locale: string, force: boolean = false)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTranslationsForComponent (plugin: Plugin, locale: string): Promise<Messages | Status> {
|
||||
async function setStatus (status: Status, skipError?: boolean): Promise<void> {
|
||||
if (skipError !== true) {
|
||||
await setPlatformStatus(status)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTranslationsForComponent (
|
||||
plugin: Plugin,
|
||||
locale: string,
|
||||
skipError?: boolean
|
||||
): Promise<Messages | Status> {
|
||||
const loader = loaders.get(plugin)
|
||||
if (loader === undefined) {
|
||||
const status = new Status(Severity.ERROR, platform.status.NoLoaderForStrings, { plugin })
|
||||
await setPlatformStatus(status)
|
||||
await setStatus(status, skipError)
|
||||
return status
|
||||
}
|
||||
try {
|
||||
@@ -79,7 +89,7 @@ async function loadTranslationsForComponent (plugin: Plugin, locale: string): Pr
|
||||
return (await loader('en')) as Record<string, IntlString> | Status
|
||||
} catch (err: any) {
|
||||
const status = unknownError(err)
|
||||
await setPlatformStatus(status)
|
||||
await setStatus(status, skipError)
|
||||
return status
|
||||
}
|
||||
}
|
||||
@@ -104,7 +114,11 @@ function getCachedTranslation (id: _IdInfo, locale: string): IntlString | Status
|
||||
}
|
||||
}
|
||||
|
||||
async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString | Status | undefined> {
|
||||
async function getTranslation (
|
||||
id: _IdInfo,
|
||||
locale: string,
|
||||
skipError?: boolean
|
||||
): Promise<IntlString | Status | undefined> {
|
||||
try {
|
||||
const localtTanslations = translations.get(locale) ?? new Map<Plugin, Messages | Status<any>>()
|
||||
if (!translations.has(locale)) {
|
||||
@@ -112,7 +126,7 @@ async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString
|
||||
}
|
||||
let messages = localtTanslations.get(id.component)
|
||||
if (messages === undefined) {
|
||||
messages = await loadTranslationsForComponent(id.component, locale)
|
||||
messages = await loadTranslationsForComponent(id.component, locale, skipError)
|
||||
localtTanslations.set(id.component, messages)
|
||||
}
|
||||
if (messages instanceof Status) {
|
||||
@@ -124,7 +138,7 @@ async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString
|
||||
} else {
|
||||
let eng = englishTranslationsForMissing.get(id.component)
|
||||
if (eng === undefined) {
|
||||
eng = await loadTranslationsForComponent(id.component, 'en')
|
||||
eng = await loadTranslationsForComponent(id.component, 'en', skipError)
|
||||
englishTranslationsForMissing.set(id.component, eng)
|
||||
}
|
||||
if (eng instanceof Status) {
|
||||
@@ -137,7 +151,7 @@ async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString
|
||||
}
|
||||
} catch (err) {
|
||||
const status = unknownError(err)
|
||||
await setPlatformStatus(status)
|
||||
await setStatus(status, skipError)
|
||||
return status
|
||||
}
|
||||
}
|
||||
@@ -151,7 +165,8 @@ async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString
|
||||
export async function translate<P extends Record<string, any>> (
|
||||
message: IntlString<P>,
|
||||
params: P,
|
||||
language?: string
|
||||
language?: string,
|
||||
skipError?: boolean
|
||||
): Promise<string> {
|
||||
const locale = language ?? getMetadata(platform.metadata.locale) ?? 'en'
|
||||
const localCache = cache.get(locale) ?? new Map<IntlString, IntlMessageFormat | Status>()
|
||||
@@ -171,7 +186,7 @@ export async function translate<P extends Record<string, any>> (
|
||||
if (id.component === _EmbeddedId) {
|
||||
return id.name
|
||||
}
|
||||
const translation = getCachedTranslation(id, locale) ?? (await getTranslation(id, locale)) ?? message
|
||||
const translation = getCachedTranslation(id, locale) ?? (await getTranslation(id, locale, skipError)) ?? message
|
||||
if (translation instanceof Status) {
|
||||
localCache.set(message, translation)
|
||||
return message
|
||||
@@ -181,7 +196,7 @@ export async function translate<P extends Record<string, any>> (
|
||||
return compiled.format(params)
|
||||
} catch (err) {
|
||||
const status = unknownError(err)
|
||||
void setPlatformStatus(status)
|
||||
await setStatus(status, skipError)
|
||||
localCache.set(message, status)
|
||||
return message
|
||||
}
|
||||
@@ -194,7 +209,8 @@ export function translateCB<P extends Record<string, any>> (
|
||||
message: IntlString<P>,
|
||||
params: P,
|
||||
language: string | undefined,
|
||||
resolve: (value: string) => void
|
||||
resolve: (value: string) => void,
|
||||
skipError?: boolean
|
||||
): void {
|
||||
const locale = language ?? getMetadata(platform.metadata.locale) ?? 'en'
|
||||
const localCache = cache.get(locale) ?? new Map<IntlString, IntlMessageFormat | Status>()
|
||||
@@ -219,7 +235,7 @@ export function translateCB<P extends Record<string, any>> (
|
||||
}
|
||||
} catch (err) {
|
||||
const status = unknownError(err)
|
||||
void setPlatformStatus(status)
|
||||
void setStatus(status, skipError)
|
||||
localCache.set(message, status)
|
||||
resolve(message)
|
||||
return
|
||||
@@ -232,7 +248,7 @@ export function translateCB<P extends Record<string, any>> (
|
||||
})
|
||||
.catch((err) => {
|
||||
const status = unknownError(err)
|
||||
void setPlatformStatus(status)
|
||||
void setStatus(status, skipError)
|
||||
localCache.set(message, status)
|
||||
resolve(message)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user