Skip to content

Commit 056f1bd

Browse files
authored
Merge pull request github#22103 from github/repo-sync
repo sync
2 parents 1dcdc96 + 1905e82 commit 056f1bd

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

lib/get-data.js

+17
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,23 @@ export const getDataByLanguage = memoize((dottedPath, langCode) => {
101101
}
102102
return value
103103
} catch (error) {
104+
if (error instanceof Error && error.mark && error.message) {
105+
// It's a yaml.load() generated error!
106+
// Remember, the file that we read might have been a .yml or a .md
107+
// file. If it was a .md file, with corrupt front-matter that too
108+
// would have caused a YAMLException
109+
if (langCode !== 'en') {
110+
if (DEBUG_JIT_DATA_READS) {
111+
console.warn(`Unable to parse Yaml in (${langCode}) '${dottedPath}': ${error.message}`)
112+
}
113+
// Give it one more chance, but use English this time
114+
return getDataByDir(dottedPath, languages.en.dir)
115+
}
116+
// Always throw English Yaml reading errors. Staff writers
117+
// need to know early and explicitly that they are corrupt.
118+
throw error
119+
}
120+
104121
if (error.code === 'ENOENT') return undefined
105122
throw error
106123
}

tests/unit/get-data.js

+102-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('get-data', () => {
1313
const jaDirBefore = languages.ja.dir
1414

1515
beforeAll(() => {
16-
const dd = new DataDirectory({
16+
dd = new DataDirectory({
1717
data: {
1818
ui: {
1919
key: 'Value',
@@ -63,7 +63,7 @@ describe('get-data', () => {
6363
})
6464

6565
afterAll(() => {
66-
if (dd) dd.destroy()
66+
dd.destroy()
6767
languages.en.dir = enDirBefore
6868
languages.ja.dir = jaDirBefore
6969
})
@@ -192,3 +192,103 @@ describe('get-data', () => {
192192
}
193193
})
194194
})
195+
196+
const VALID_ENGLISH_MARKDOWN = `
197+
---
198+
front: matter
199+
---
200+
*English* /Markdown/
201+
`.trim()
202+
203+
const VALID_JAPANESE_MARKDOWN = `
204+
---
205+
front:matter
206+
---
207+
*Japanese* /Markdown/
208+
`.trim()
209+
210+
const INVALID_JAPANESE_MARKDOWN = `
211+
---
212+
front: >'matter
213+
---
214+
*Japanese* /Markdown/
215+
`.trim()
216+
217+
describe('get-data on corrupt translations', () => {
218+
let dd
219+
const enDirBefore = languages.en.dir
220+
const jaDirBefore = languages.ja.dir
221+
222+
beforeAll(() => {
223+
dd = new DataDirectory({
224+
data: {
225+
variables: {
226+
everything: {
227+
is: 'Awesome',
228+
},
229+
},
230+
reusables: {
231+
cool: VALID_ENGLISH_MARKDOWN,
232+
},
233+
},
234+
})
235+
languages.en.dir = dd.root
236+
237+
const jaTranslationsRoot = path.join(dd.root, 'translations', 'ja-JP')
238+
fs.mkdirSync(jaTranslationsRoot, { recursive: true })
239+
languages.ja.dir = jaTranslationsRoot
240+
new DataDirectory( // eslint-disable-line no-new
241+
{
242+
data: {
243+
variables: {
244+
everything: {
245+
is: 'just you wait',
246+
},
247+
},
248+
reusables: {
249+
cool: VALID_JAPANESE_MARKDOWN,
250+
},
251+
},
252+
},
253+
jaTranslationsRoot
254+
)
255+
const ymlFile = path.join(jaTranslationsRoot, 'data', 'variables', 'everything.yml')
256+
console.assert(fs.existsSync(ymlFile), `${ymlFile} wasn't created`)
257+
fs.writeFileSync(ymlFile, `>:This is not valid Yaml:>`, 'utf-8')
258+
const mdFile = path.join(jaTranslationsRoot, 'data', 'reusables', 'cool.md')
259+
console.assert(fs.existsSync(mdFile), `${mdFile} wasn't created`)
260+
fs.writeFileSync(mdFile, INVALID_JAPANESE_MARKDOWN, 'utf-8')
261+
})
262+
263+
afterAll(() => {
264+
dd.destroy()
265+
languages.en.dir = enDirBefore
266+
languages.ja.dir = jaDirBefore
267+
})
268+
269+
test('getDataByLanguage on a corrupt .yml file', () => {
270+
// First make sure it works in English
271+
{
272+
const result = getDataByLanguage('variables.everything.is', 'en')
273+
expect(result).toBe('Awesome')
274+
}
275+
// Japanese translations would fall back due to a corrupt Yaml file
276+
{
277+
const result = getDataByLanguage('variables.everything.is', 'ja')
278+
expect(result).toBe('Awesome')
279+
}
280+
})
281+
282+
test('getDataByLanguage on a corrupt .md file', () => {
283+
// First make sure it works in English
284+
{
285+
const result = getDataByLanguage('reusables.cool', 'en')
286+
expect(result).toBe('*English* /Markdown/')
287+
}
288+
// Japanese translations would fall back due to a corrupt Yaml file
289+
{
290+
const result = getDataByLanguage('reusables.cool', 'ja')
291+
expect(result).toBe('*English* /Markdown/')
292+
}
293+
})
294+
})

0 commit comments

Comments
 (0)