eo-locale
eo-locale copied to clipboard
No Error on missing Translation
For the Company im working we use eo-locale in several React-UIs and are pleased ā Thanks for the great Work.
In several situations I miss the option to disable the '[eo-locale] id missing ...' Error.
F.E. the API delivers an status-key and an fallback message. Each Region has its own (huge) set of status. Some of the status-keys should be translated, some not. In this case, using the fallback message is wanted. But it throws an Error that pollutes our monitoring...
I miss an option, to disable the Error or know if a id exists.
If there should be something implemented, I could create a pull request. I would like to know witch is the desired Version. I have several implementation approaches:
Would love to here if an implementation is wished and if I can help.
via parameter
extend getMessageById by a custom paramter. The Smallest Option.
public getMessageById = (
id: string,
defaultMessage?: string,
// Optional Parameter
ignoreMissing? boolean,
): Message | object | null => {
if (!this.memo[id]) {
let message: object | string | undefined = id
.split('.')
.reduce(
(acc, current) => (acc ? (acc as any)[current] : undefined),
this.messages,
);
if (typeof message !== 'string') {
// Wrap Error
if (!ignoreMissing) {
this.onError(new Error(`[eo-locale] id missing "${id}"`));
}
message = defaultMessage || id;
}
this.memo[id] = message;
}
return this.memo[id];
};
via method
a dedicated Method would return a boolean value. Maybe the more intuitive version. Bitewise perhaps the biggest option.
public hasMessage = (
id: string,
): boolean => {
if (!this.issetMemo[id]) {
let message: object | string | undefined = id
.split('.')
.reduce(
(acc, current) => (acc ? (acc as any)[current] : undefined),
this.messages,
);
this.issetMemo[id] = typeof message === 'string';
}
return this.issetMemo[id];
};
more customizable onError / dedicated onMissing
with a custom Missing Logger that receives some more information, a custom filter can be implemented or even more advanced messages could be implemented.
export class Translator {
// ...
// Add separate logger for Missing - can be overwritten with custom logger
public onMissing: MissingLogger = (id, {options, languages}) => {
// downward compatible
this.onError(new Error(`[eo-locale] id missing "${id}"`))
}
// ...
public translate = (
id: string,
options: FormatMessageOptions = {},
): string => {
// Add options
const message = this.getMessageById(id, options.defaultMessage, options);
// ...
return String(message);
};
public getMessageById = (
id: string,
defaultMessage?: string,
// Add option (only for Logging) - could be merged with / replace defaultMessage with working downward compatible
_options: FormatMessageOptions = {},
): Message | object | null => {
// ...
if (typeof message !== 'string') {
// Use onMissing
this.onMissing(
id,
{
options: _options,
language: this.language,
}
);
// ...
}
// ...
};
}
export type ErrorLogger = (error: Error) => void;
export type MissingLogger = (id: string, {options: FormatMessageOptions, language: string, }
In the Project setting a custom onMissing with a custom option could filter the Error or do custom logging:
translator.onMissing = (id, {options, language}) => {
if (!options.ignoreMissing) {
console.warn(`[UI-Name] - missing translation for '${id}' in ${language}`)
}
}
const text = translator.translate('unknown', {ignoreMissing: true, defaultMessage: 'fallback {param}', param: 'PARAM'})
// text: 'fallback PARAM'
Hi @mi-roh! Thanks for the issue. You can provide custom onError
handler to TranslationsProvider
component as property. By default it is console.error
.
@mi-roh Does it work for you? Shall I close the issue?
Hi @pret-a-porter, not really. In my subjective view, onError is ideal to link eo-locale with your monitoring. But its not useful to prefilter messages.
We already use a custom onError for our monitoring. But there is no way to filter between the Errors passed. Beside of filter on the Error-Message-Shema and grabbing the missing id with an regex.
What I haven't mentioned in my first post. Within onError there is no way to detect if a default message was used. Even that little Information would optimize the filter options.
f.e.:
this.onError(new Error(`[eo-locale] id missing "${id}" in ${this.language}. Displayed "${message}" instead.`))
I created a fork with two commits. First adds a custom missing handler. To prevent regexing on error messages. Second passes the FormatMessageOptions down to the missing handler. Custom filters or logging messages are possible for there is now a context given.
With a wrapper and some regexing we get the job done. I don't know if I'm the only one how would like to prefilter. But I would be happy for every little improvement. Even if only something like Displayed "${message}" instead.
gets added to the Error.