11import path from 'path'
22
3+ import { createLogger } from '@/observability/logger'
34import languages from '@/languages/lib/languages-server'
45import type { Language } from '@/languages/lib/languages'
56import type { UnversionedTree , UnversionLanguageTree , SiteTree , Tree } from '@/types'
@@ -13,6 +14,8 @@ import Permalink from './permalink'
1314import frontmatterSchema from './frontmatter'
1415import { correctTranslatedContentStrings } from '@/languages/lib/correct-translation-content'
1516
17+ const logger = createLogger ( import . meta. url )
18+
1619interface FileSystemError extends Error {
1720 code ?: string
1821}
@@ -31,7 +34,13 @@ const THROW_TRANSLATION_ERRORS = Boolean(
3134
3235const versions = Object . keys ( allVersions )
3336
34- class FrontmatterParsingError extends Error { }
37+ class FrontmatterParsingError extends Error {
38+ isYmlError : boolean
39+ constructor ( message : string , isYmlError = false ) {
40+ super ( message )
41+ this . isYmlError = isYmlError
42+ }
43+ }
3544
3645// Note! As of Nov 2022, the schema says that 'product' is translatable
3746// which is surprising since only a single page has prose in it.
@@ -170,7 +179,7 @@ async function translateTree(
170179 //
171180 // If this the case throw error so we can lump this error with
172181 // how we deal with the file not even being present on disk.
173- throw new FrontmatterParsingError ( JSON . stringify ( read . errors ) )
182+ throw new FrontmatterParsingError ( JSON . stringify ( read . errors ) , true )
174183 }
175184
176185 for ( const { property } of read . errors ) {
@@ -187,7 +196,7 @@ async function translateTree(
187196 const message = `frontmatter error on '${ property } ' (in ${ fullPath } ) so falling back to English`
188197 if ( DEBUG_TRANSLATION_FALLBACKS ) {
189198 // The object format is so the health report knows which path the issue is on
190- console . warn ( { message, path : relativePath } )
199+ logger . warn ( message , { path : relativePath } )
191200 }
192201 if ( THROW_TRANSLATION_ERRORS ) {
193202 throw new Error ( message )
@@ -202,10 +211,17 @@ async function translateTree(
202211 if ( ( error as FileSystemError ) . code === 'ENOENT' || error instanceof FrontmatterParsingError ) {
203212 data = enData
204213 content = enPage . markdown
205- const message = `Unable to initialize ${ fullPath } because translation content file does not exist.`
206- if ( DEBUG_TRANSLATION_FALLBACKS ) {
207- // The object format is so the health report knows which path the issue is on
208- console . warn ( { message, path : relativePath } )
214+ const message =
215+ error instanceof FrontmatterParsingError && error . isYmlError
216+ ? `Unable to parse YAML frontmatter in ${ fullPath } , falling back to English. Details: ${ error . message } `
217+ : `Unable to initialize ${ fullPath } because translation content file does not exist.`
218+ if ( error instanceof FrontmatterParsingError && error . isYmlError ) {
219+ // YAML parse failures are always logged — they indicate a translation file is corrupt
220+ // and will silently serve English until the translation repo is fixed.
221+ logger . warn ( message , { path : relativePath } )
222+ } else if ( DEBUG_TRANSLATION_FALLBACKS ) {
223+ // Missing translation files are expected and high-volume; only log when opted in.
224+ logger . warn ( message , { path : relativePath } )
209225 }
210226 if ( THROW_TRANSLATION_ERRORS ) {
211227 throw new Error ( message )
0 commit comments