{"record":{"id":"65e8c33bb9002add","repo":"jackwener/OpenCLI","slug":"error-65e8c3","errorCode":null,"errorMessage":"无法获取简历面板: ","messagePattern":"无法获取简历面板: ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/boss/resume.js","lineNumber":135,"sourceCode":"          if (eduTimes[i]) parts.push(eduTimes[i]);\n          if (eduDetails[i]) parts.push(eduDetails[i]);\n          if (parts.length) education.push(parts.join('  '));\n        }\n\n        const positionContent = container.querySelector('.position-content');\n        let jobChatting = '', expect = '';\n        if (positionContent) {\n          const posNameEl = positionContent.querySelector('.position-name');\n          if (posNameEl) jobChatting = posNameEl.textContent.trim();\n          const expectEl = positionContent.querySelector('.position-item.expect .value');\n          if (expectEl) expect = expectEl.textContent.trim();\n        }\n\n        return { name, gender, age, experience, degree, activeTime, workHistory, education, jobChatting, expect };\n      })()\n    `);\n        if (resumeInfo.error) {\n            throw new Error('无法获取简历面板: ' + resumeInfo.error);\n        }\n        return [{\n                name: resumeInfo.name || friend.name || '',\n                gender: resumeInfo.gender || '',\n                age: resumeInfo.age || '',\n                experience: resumeInfo.experience || '',\n                degree: resumeInfo.degree || '',\n                active_time: resumeInfo.activeTime || '',\n                work_history: (resumeInfo.workHistory || []).join('\\\\n') || '(未获取到)',\n                education: (resumeInfo.education || []).join('\\\\n') || '(未获取到)',\n                job_chatting: resumeInfo.jobChatting || '',\n                expect: resumeInfo.expect || '',\n            }];\n    },\n});\n","sourceCodeStart":117,"sourceCodeEnd":151,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/boss/resume.js#L117-L151","documentation":"Thrown after the in-page evaluate() scrapes the resume panel; if the injected script returned an error property (selectors missing, page not loaded), the command surfaces it as '无法获取简历面板: <inner error>'. It means the right-hand resume panel DOM was not in the expected state when scraping ran.","triggerScenarios":"clickCandidateInList succeeded but the resume panel had not rendered yet (the fixed 2s wait was insufficient), BOSS changed its panel class names (.base-info-single-container / .base-info-content), or the click opened the wrong/empty view.","commonSituations":"Slow network or heavy page making 2 seconds insufficient; BOSS front-end redesign renaming CSS classes; candidate profile page layout differs (e.g. greeting overlay blocking render); running headless where lazy content never loads.","solutions":["Increase the wait after clicking the candidate (e.g. page.wait({ time: 5 })) or poll for '.base-info-content' before evaluating","Re-run the command once — transient render delays are the most common cause","Inspect the live page and update the scraped selectors if BOSS changed its DOM","Verify the candidate's profile actually renders in the browser manually","Check the inner error text appended after the colon to identify the specific scrape failure"],"exampleFix":"// before\nconst clicked = await clickCandidateInList(page, numericUid);\nawait page.wait({ time: 2 });\nconst resumeInfo = await page.evaluate(`...`);\n// after\nawait clickCandidateInList(page, numericUid);\nawait page.waitForSelector('.base-info-content', { timeout: 10000 });\nconst resumeInfo = await page.evaluate(`...`);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const resume = await cli('boss', 'resume', { uid });\n} catch (e) {\n  if (String(e.message).startsWith('无法获取简历面板')) {\n    await sleep(3000); // give the panel more time, retry once\n    return retryResume(uid);\n  }\n  throw e;\n}","preventionTips":["Wait for '.base-info-content' to appear before scraping rather than relying on fixed waits","Re-run once on transient render failures","Watch for BOSS DOM changes and update selectors","Use verbose mode to see which selector failed from the inner error"],"tags":["scraping","dom-selector","render-timing"],"backgroundTag":"dom-element-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}