{"record":{"id":"690d79c8bf8ef6b0","repo":"jackwener/OpenCLI","slug":"parsed-message-parsed-msg-xiaoyuzhou-ap-690d79","errorCode":null,"errorMessage":"${parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false'}","messagePattern":"\\$\\{parsed\\?\\.message \\|\\| parsed\\?\\.msg \\|\\| 'Xiaoyuzhou API returned success=false'\\}","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaoyuzhou/auth.js","lineNumber":249,"sourceCode":"        throw new CommandExecutionError(`Xiaoyuzhou API returned invalid JSON: ${getErrorMessage(error)}`);\n    }\n    const serviceCode = parsed?.code;\n    if (serviceCode !== undefined && serviceCode !== null) {\n        const numericCode = Number(serviceCode);\n        if (!Number.isFinite(numericCode)) {\n            throw new CommandExecutionError('Xiaoyuzhou API returned an invalid service code');\n        }\n        if (numericCode === 401 || numericCode === 403) {\n            throw createXiaoyuzhouAuthError(`Xiaoyuzhou API rejected the credentials with service code ${numericCode}`);\n        }\n        if (numericCode !== 0 && numericCode !== 200) {\n            throw new CommandExecutionError(\n                parsed?.message || parsed?.msg || `Xiaoyuzhou API returned service code ${numericCode}`,\n            );\n        }\n    }\n    if (parsed?.success === false) {\n        throw new CommandExecutionError(parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false');\n    }\n    return {\n        credentials,\n        raw: parsed,\n        data: parsed?.data,\n    };\n}\n\nexport async function fetchXiaoyuzhouTranscriptBody(url, fetchImpl = fetch) {\n    let response;\n    try {\n        response = await fetchImpl(url, {\n            method: 'GET',\n            headers: {\n                'User-Agent': XIAOYUZHOU_DEFAULT_USER_AGENT,\n                Accept: '*/*',\n                Market: 'AppStore',\n            },","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoyuzhou/auth.js#L231-L267","documentation":"Some Xiaoyuzhou responses use a success boolean instead of (or in addition to) a numeric code. If parsed.success === false and no code-based failure was already caught, requestXoyuzhouJson throws CommandExecutionError with the API's message/msg field or a fallback string. This guards against bodies that are valid JSON with a passing code but explicitly marked unsuccessful.","triggerScenarios":"parsed.success is exactly false (strict ===) while code was absent or 0/200 — e.g. endpoints that return {success:false, message:'...'} envelopes for business-logic failures like paywalled content or incomplete data.","commonSituations":"Requesting premium/paywalled episode data with a free account; partial outages where the backend signals degraded success; endpoints that mix envelope styles (code-based vs success-based) and return success:false for soft failures.","solutions":["Read parsed.message/msg in the error output — the API explains the soft failure (e.g. permission, content unavailable).","Verify the account has access rights to the requested content (subscription/paywall status).","Confirm the requested resource exists and parameters (IDs, ranges) are valid.","If this endpoint legitimately uses success:false semantics, update the CLI to branch on it explicitly instead of treating it as generic failure."],"exampleFix":"// before: throws with fallback text only\nthrow new CommandExecutionError(parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false');\n// after: include the raw payload for diagnosis\nthrow new CommandExecutionError(`${parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false'}; payload=${JSON.stringify(parsed).slice(0, 300)}`);","handlingStrategy":"validation","validationCode":"// pre-flight: confirm account access tier covers the requested resource\nconst account = await getXiaoyuzhouAccountInfo(creds);\nif (requiresSubscription(resource) && !account.isSubscribed) {\n  throw new Error(`Resource ${resource.id} requires a subscription; account is free tier`);\n}","typeGuard":"function isApiSuccessEnvelope(parsed) {\n  return typeof parsed === 'object' && parsed !== null &&\n    (parsed.success === undefined || parsed.success === true);\n}","tryCatchPattern":"try {\n  const result = await requestXiaoyuzhouJson(creds, path, params);\n} catch (e) {\n  if (e.message.includes('success=false')) {\n    // soft business failure: surface parsed.message to the user, don't retry blindly\n    console.error('API rejected request:', e.message);\n  } else throw e;\n}","preventionTips":["Check subscription/permission requirements for content before requesting it.","Verify requested IDs and parameters exist via a listing endpoint first.","Log the full envelope on success=false — message/msg explains the soft failure.","Treat success=false as permanent; don't retry without changing the request.","Add tests for endpoints known to use success-based envelopes."],"tags":["api-response","service-error","validation","schema"],"backgroundTag":"api-success-false-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}