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`. | ||||
|  * 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( | ||||
|     translations: Record<string, ParsedTranslation>, messageParts: TemplateStringsArray, | ||||
| @ -42,8 +44,14 @@ export function translate( | ||||
|   const translation = translations[message.messageId]; | ||||
|   if (translation !== undefined) { | ||||
|     return [ | ||||
|       translation.messageParts, | ||||
|       translation.placeholderNames.map(placeholder => message.substitutions[placeholder]) | ||||
|       translation.messageParts, translation.placeholderNames.map(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 { | ||||
|     throw new Error( | ||||
|  | ||||
| @ -80,6 +80,18 @@ describe('utils', () => { | ||||
|   }); | ||||
| 
 | ||||
|   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', () => { | ||||
|       const translations = { | ||||
|         'abc': 'abc', | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user