{"record":{"id":"36571479e1022800","repo":"pot-app/pot-desktop","slug":"words-not-yet-included-text","errorCode":null,"errorMessage":"Words not yet included: ${text}","messagePattern":"Words not yet included: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/services/translate/cambridge_dict/index.jsx","lineNumber":58,"sourceCode":"        return '';\n    }\n\n    const url = `https://dictionary.cambridge.org/search/direct/?datasetsearch=${from}-${to}&q=${text}`;\n    let res = await fetch(url, {\n        method: 'GET',\n        headers: {\n            'Content-Type': 'text/html;charset=UTF-8',\n        },\n        responseType: 2,\n    });\n\n    if (!res.ok) {\n        throw new Error(`Http Request Error\\nHttp Status: ${res.status}\\n${JSON.stringify(res.data)}`);\n    }\n    const doc = new DOMParser().parseFromString(res.data, 'text/html');\n    const entryNodes = doc.querySelectorAll('.pr.entry-body__el');\n    if (entryNodes.length === 0) {\n        throw new Error(`Words not yet included: ${text}`);\n    }\n\n    const resultMap = [...entryNodes].reduce((dict, entryNode) => {\n        const wordTranslateResult = dict['result'] || new WordTranslateResult([], []);\n\n        if (wordTranslateResult.pronunciations.length === 0) {\n            const pronunciationNodes = entryNode.querySelectorAll('.dpron-i');\n            const pronunciations = [...pronunciationNodes].map((pronunciationNode) => {\n                const region = pronunciationNode.querySelector('.region').innerText;\n                const symbol = pronunciationNode.querySelector('.pron').innerText;\n                let voice = pronunciationNode.querySelector('.daud source').src;\n                voice = voice.replace(/^https?:\\/\\/[^/]+/, 'https://dictionary.cambridge.org');\n                voice = voice.replace(/^tauri:\\/\\/[^/]+/, 'https://dictionary.cambridge.org');\n                return new Pronunciation(region, symbol, voice);\n            });\n            wordTranslateResult.pronunciations.push(...pronunciations);\n        }\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/pot-app/pot-desktop/blob/594d32ede96acd106b0256deaa8bb440ffcdff40/src/services/translate/cambridge_dict/index.jsx#L40-L76","documentation":"After a successful (2xx) fetch, the service parses the HTML and queries for `.pr.entry-body__el` nodes — the containers holding dictionary entries. If none are found, Cambridge returned a page with no dictionary entry for the queried word, so the service throws this error instead of returning an empty result. The library does this because its parser relies entirely on that DOM structure.","triggerScenarios":"translate(text, from, to) receives a single English word (passes the guard at line 39) but Cambridge has no entry for it: misspelled words, proper nouns, slang, very new/rare terms, or non-English input that slipped through auto-detection.","commonSituations":"User highlights a misspelled word or a brand/product name and triggers the Cambridge dictionary service; Cambridge page layout changes removing the `entry-body__el` class; the word exists only in a different dictionary dataset than the selected from-to pair.","solutions":["Check the spelling of the queried word and correct it before translating.","Use a different translation service (e.g. an LLM or Bing) for words not in the Cambridge dictionary.","If this happens for words that DO exist on the website, inspect the returned HTML — Cambridge likely changed its CSS classes; update the `.pr.entry-body__el` selector.","Treat this error as expected behavior for unknown words and show a friendly 'not found' message instead of a stack trace."],"exampleFix":"// before\nif (entryNodes.length === 0) {\n    throw new Error(`Words not yet included: ${text}`);\n}\n// after\nif (entryNodes.length === 0) {\n    return ''; // or return new WordTranslateResult([], []) to degrade gracefully\n}","handlingStrategy":"fallback","validationCode":"const likelyDictionaryWord = (text) => /^[A-Za-z][A-Za-z'-]*$/.test(text.trim());\nif (!likelyDictionaryWord(text)) return ''; // names, typos, multi-words won't be in the dictionary","typeGuard":"function hasDictionaryEntries(doc) {\n  return doc.querySelectorAll('.pr.entry-body__el').length > 0;\n}","tryCatchPattern":"try {\n  const result = await cambridgeTranslate(word, 'en', to);\n} catch (e) {\n  if (String(e.message).startsWith('Words not yet included')) {\n    return null; // render as 'word not found', not as an error\n  }\n  throw e;\n}","preventionTips":["Only send single, correctly spelled English words to this service","Fall back to a full translation service (LLM/Bing) when the word isn't in the dictionary","Surface 'not found' as informational, not as a failure","Watch for a sudden spike of this error on common words — it signals a Cambridge DOM change"],"tags":["dom-parsing","scraping","not-found","cambridge-dictionary"],"backgroundTag":"selector-matched-nothing","analyzedSha":"594d32ede96acd106b0256deaa8bb440ffcdff40","analyzedAt":"2026-09-02T18:12:21.811Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}