diff --git a/i18n/index.js b/i18n/index.js index 220ac2d7c6311..0fe5a7e423c54 100644 --- a/i18n/index.js +++ b/i18n/index.js @@ -2,9 +2,19 @@ * External dependencies */ import Jed from 'jed'; +import memoize from 'memize'; let i18n; +/** + * Log to console, once per message; or more precisely, per referentially equal + * argument set. Because Jed throws errors, we log these to the console instead + * to avoid crashing the application. + * + * @param {...*} args Arguments to pass to `console.error` + */ +const logErrorOnce = memoize( console.error ); // eslint-disable-line no-console + /** * Merges locale data into the Jed instance by domain. Creates a new Jed * instance if one has not yet been assigned. @@ -59,11 +69,7 @@ export function dcnpgettext( domain = 'default', context, single, plural, number try { return getI18n().dcnpgettext( domain, context, single, plural, number ); } catch ( error ) { - // Disable reason: Jed throws errors. To avoid crashing the application - // we log these to the console instead, and return a default value. - - // eslint-disable-next-line no-console - console.error( 'Jed localization error: \n\n' + error.toString() ); + logErrorOnce( 'Jed localization error: \n\n' + error.toString() ); return single; } @@ -150,11 +156,7 @@ export function sprintf( format, ...args ) { try { return Jed.sprintf( format, ...args ); } catch ( error ) { - // Disable reason: Jed throws errors. To avoid crashing the application - // we log these to the console instead, and return a default value. - - // eslint-disable-next-line no-console - console.error( 'Jed sprintf error: \n\n' + error.stack ); + logErrorOnce( 'Jed sprintf error: \n\n' + error.toString() ); return format; } diff --git a/i18n/test/index.js b/i18n/test/index.js index 6b4fb2687f29e..bd7e6cce4069c 100644 --- a/i18n/test/index.js +++ b/i18n/test/index.js @@ -3,6 +3,10 @@ */ import { dcnpgettext, sprintf } from '../'; +// Mock memoization as identity function. Inline since Jest errors on out-of- +// scope references in a mock callback. +jest.mock( 'memize', () => ( fn ) => fn ); + describe( 'i18n', () => { describe( 'dcnpgettext()', () => { it( 'absorbs errors', () => {