fix(ivy): i18n - throw an error if a translation contains an invalid placeholder (#32867)
Previously if a translation contains a placeholder that does not exist in the message being translated, that placeholder is evaluated as `undefined`. Translations should never contain such placeholder names so now `translate` will throw a helpful error in instead. PR Close #32867
This commit is contained in:
parent
052cae6427
commit
601f87c2ec
@ -33,7 +33,9 @@ export type ParsedTranslations = Record<MessageId, ParsedTranslation>;
|
|||||||
* `substitutions`.
|
* `substitutions`.
|
||||||
* The translation may reorder (or remove) substitutions as appropriate.
|
* The translation may reorder (or remove) substitutions as appropriate.
|
||||||
*
|
*
|
||||||
* If no translation matches then an error is thrown.
|
* If there is no translation with a matching message id then an error is thrown.
|
||||||
|
* If a translation contains a placeholder that is not found in the message being translated then an
|
||||||
|
* error is thrown.
|
||||||
*/
|
*/
|
||||||
export function translate(
|
export function translate(
|
||||||
translations: Record<string, ParsedTranslation>, messageParts: TemplateStringsArray,
|
translations: Record<string, ParsedTranslation>, messageParts: TemplateStringsArray,
|
||||||
@ -42,8 +44,14 @@ export function translate(
|
|||||||
const translation = translations[message.messageId];
|
const translation = translations[message.messageId];
|
||||||
if (translation !== undefined) {
|
if (translation !== undefined) {
|
||||||
return [
|
return [
|
||||||
translation.messageParts,
|
translation.messageParts, translation.placeholderNames.map(placeholder => {
|
||||||
translation.placeholderNames.map(placeholder => message.substitutions[placeholder])
|
if (message.substitutions.hasOwnProperty(placeholder)) {
|
||||||
|
return message.substitutions[placeholder];
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`No placeholder found with name ${placeholder} in message "${message.messageId}" ("${message.messageString}").`);
|
||||||
|
}
|
||||||
|
})
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -80,6 +80,18 @@ describe('utils', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('translate', () => {
|
describe('translate', () => {
|
||||||
|
it('should throw an error if there is no matching translation', () => {
|
||||||
|
expect(() => doTranslate({}, parts `abc`))
|
||||||
|
.toThrowError('No translation found for "2674653928643152084" ("abc").');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the translation contains placeholders that are not in the message',
|
||||||
|
() => {
|
||||||
|
expect(() => doTranslate({'abc': 'a{$PH}bc'}, parts `abc`))
|
||||||
|
.toThrowError(
|
||||||
|
'No placeholder found with name PH in message "2674653928643152084" ("abc").');
|
||||||
|
});
|
||||||
|
|
||||||
it('(with identity translations) should render template literals as-is', () => {
|
it('(with identity translations) should render template literals as-is', () => {
|
||||||
const translations = {
|
const translations = {
|
||||||
'abc': 'abc',
|
'abc': 'abc',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user