{"record":{"id":"42d03944c29d589c","repo":"jackwener/OpenCLI","slug":"dianping-com-42d039","errorCode":null,"errorMessage":"dianping.com","messagePattern":"dianping\\.com","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/dianping/utils.js","lineNumber":107,"sourceCode":"    return Promise.resolve()\n        .then(fn)\n        .catch((err) => {\n            if (err?.code) throw err;\n            const message = err?.message || String(err);\n            throw new CommandExecutionError(`dianping ${label} failed: ${message}`);\n        });\n}\n\n/**\n * Throw the right typed error for a dianping page that didn't render data.\n * The site short-circuits HTML when bot/login checks trip — typically\n * redirects to verify.meituan.com (Yoda icon-tap captcha) or to a login\n * page when the cookie is missing.\n */\nexport function detectAuthOrPageFailure({ text = '', url = '' }, contextHint, { emptyPatterns = [] } = {}) {\n    const signal = `${url} ${text}`;\n    if (/verify\\.meituan\\.com|verifyimg|身份核实|请依次点击|美团安全验证|Yoda/i.test(signal)) {\n        throw new AuthRequiredError(\n            'dianping.com',\n            `dianping ${contextHint} blocked by captcha — open ${url || 'www.dianping.com'} manually in this profile and solve the captcha, then retry`,\n        );\n    }\n    if (/login\\.dianping\\.com|account\\.dianping\\.com|请先登录|未登录|请登录/.test(signal)) {\n        throw new AuthRequiredError(\n            'dianping.com',\n            `dianping ${contextHint} requires login — sign in to dianping.com in this profile, then retry`,\n        );\n    }\n    if (emptyPatterns.some((pattern) => pattern.test(signal))) {\n        throw new EmptyResultError(`dianping ${contextHint}`);\n    }\n    const sample = text ? `; sample: ${String(text).slice(0, 160)}` : '';\n    throw new CommandExecutionError(\n        `dianping ${contextHint} did not render expected data${sample}`,\n        'This usually means dianping changed its HTML, returned an unexpected error page, or the browser profile hit an unrecognized anti-bot state.',\n    );","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dianping/utils.js#L89-L125","documentation":"detectAuthOrPageFailure inspects the rendered page text and final URL of a dianping request. When the signal matches captcha indicators (verify.meituan.com, verifyimg, 身份核实, 请依次点击, 美团安全验证, Yoda) it throws AuthRequiredError('dianping.com', ...) telling you the request was blocked by Meituan's Yoda icon-tap captcha. Dianping short-circuits HTML to this captcha when its bot checks trip, so no real data was rendered.","triggerScenarios":"Any dianping step that calls detectAuthOrPageFailure while the page URL/text contains a meituan verification redirect — typically after several automated requests from one cookie profile, an aged/flagged cookie, or a headless fingerprint that trips anti-bot checks.","commonSituations":"Scraping many search pages back-to-back from the same profile, running headless with default browser flags, reusing a cookie jar that dianping has flagged, or a datacenter IP making the session suspicious.","solutions":["Open the reported URL (or www.dianping.com) manually in the same browser profile and solve the captcha, then retry the command.","Slow down: add delays between requests and reduce request volume per profile.","Refresh/replace the dianping login cookies with a freshly authenticated session.","Run non-headless (or with a more realistic fingerprint) and avoid datacenter IPs; if it recurs, wait before retrying to let the rate-limit cool down."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// quick session probe before scraping\nconst res = await page.goto('https://www.dianping.com');\nconst signal = `${page.url()} ${await page.content()}`;\nif (/verify\\.meituan\\.com|verifyimg|身份核实|请依次点击|美团安全验证|Yoda/i.test(signal)) {\n  throw new Error('captcha pending — solve it in the browser profile first');\n}","typeGuard":"function isAuthRequiredError(err) {\n  return err instanceof Error && err.code === 'AUTH_REQUIRED' && /captcha/i.test(err.message || '');\n}","tryCatchPattern":"try {\n  await dianpingSearch(args);\n} catch (err) {\n  if (err.code === 'AUTH_REQUIRED' && /captcha/i.test(err.message)) {\n    console.error('Solve the captcha in the browser profile, then rerun.');\n    process.exitCode = 2;\n  } else throw err;\n}","preventionTips":["Throttle request rate and add randomized delays between dianping calls.","Use a logged-in, human-used browser profile rather than a fresh headless one.","Avoid datacenter IPs; run from a residential connection when possible.","Pause scraping after any captcha until it is solved — repeated attempts deepen the flag."],"tags":["captcha","anti-bot","authentication","dianping"],"backgroundTag":"captcha-required","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}