Skip to content

Commit

Permalink
fix: ignore errors when loading dicts
Browse files Browse the repository at this point in the history
  • Loading branch information
schummar committed Jan 15, 2024
1 parent e32b5da commit 93a9953
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 169 deletions.
30 changes: 20 additions & 10 deletions src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,19 @@ export class Store<D extends Dict = any, ProvidedArgs extends string = never> {
if (match([locale], [this.options.sourceLocale], '') && this.options.sourceDictionary) {
dict = this.options.sourceDictionary;
} else if (this.options.dicts instanceof Function) {
dict = this.options.dicts(locale);
try {
dict = this.options.dicts(locale);

if (dict instanceof Promise) {
dict = dict.catch(() => {
console.warn(`Failed to load dictionary for locale "${locale}"`);
return null;
});
}
} catch {
console.warn(`Failed to load dictionary for locale "${locale}"`);
dict = null;
}
} else if (this.options.dicts) {
const availableLocales = Object.keys(this.options.dicts);
const matching = match([locale], availableLocales, locale);
Expand All @@ -28,15 +40,13 @@ export class Store<D extends Dict = any, ProvidedArgs extends string = never> {
}

if (dict instanceof Promise) {
entry = dict
.then((resolvedDict) => {
const flatDict = resolvedDict && flattenDict(resolvedDict);
if (this.dicts.get(locale) === entry) {
this.dicts.set(locale, flatDict);
}
return flatDict;
})
.catch(() => null);
entry = dict.then((resolvedDict) => {
const flatDict = resolvedDict && flattenDict(resolvedDict);
if (this.dicts.get(locale) === entry) {
this.dicts.set(locale, flatDict);
}
return flatDict;
});
} else {
entry = dict && flattenDict(dict);
}
Expand Down
59 changes: 58 additions & 1 deletion test/react.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { act, fireEvent, render, screen } from '@testing-library/react';
import React, { ReactNode, useState } from 'react';
import { beforeEach, expect, test } from 'vitest';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { FlattenDict } from '../src';
import { HookTranslator, MaybePromise, TranslationContextProvider, createTranslator } from '../src/react';
import { dictDe, dictEn, dictEs, wait } from './_helpers';
Expand All @@ -25,6 +25,11 @@ beforeEach(() => {
}));
});

const originalConsoleWarn = console.warn;
afterEach(() => {
console.warn = originalConsoleWarn;
});

function App({
id,
locales = ['en', 'de', 'es'],
Expand Down Expand Up @@ -441,3 +446,55 @@ test('provided args', async () => {

expect(div.textContent).toBe('1');
});

describe('error in dict loader', () => {
test('sync error', async () => {
console.warn = vi.fn();

const { t: _t } = createTranslator({
sourceLocale: 'en',
sourceDictionary: dictEn,
fallbackLocale: 'en',
dicts(locale) {
throw new Error(`dicts error: ${locale}`);
},
});

render(
<App id={'error'} locales={['de']}>
{_t('key1')}
</App>,
);
const div = screen.getByTestId('error');

expect(div.textContent).toBe('key1:en');
expect(console.warn).toHaveBeenCalledWith('Failed to load dictionary for locale "de"');
});

test('async error', async () => {
console.warn = vi.fn();

const { t: _t } = createTranslator({
sourceLocale: 'en',
sourceDictionary: dictEn,
fallbackLocale: 'en',
placeholder: '...',
dicts(locale) {
return Promise.reject(new Error(`dicts error: ${locale}`));
},
});

render(
<App id={'error'} locales={['de']}>
{_t('key1')}
</App>,
);
const div = screen.getByTestId('error');
await act(async () => {
await wait(10);
});

expect(div.textContent).toBe('key1:en');
expect(console.warn).toHaveBeenCalledWith('Failed to load dictionary for locale "de"');
});
});
Loading

0 comments on commit 93a9953

Please sign in to comment.