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