{"record":{"id":"780b343e7a65db05","repo":"lyswhut/lx-music-desktop","slug":"unknown-action-action-780b34","errorCode":null,"errorMessage":"Unknown action: ${action}","messagePattern":"Unknown action: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/core/useApp/useDeeplink/useSonglistAction.js","lineNumber":110,"sourceCode":"\n    await playSongListDetail(songlistInfo.source, songlistInfo.id ?? songlistInfo.url, songlistInfo.index)\n  }\n}\n\nexport default () => {\n  const handleOpenSonglist = useOpenSonglist()\n  const handlePlaySonglist = usePlaySonglistDetail()\n\n\n  return async(action, info) => {\n    switch (action) {\n      case 'open':\n        handleOpenSonglist(info)\n        break\n      case 'play':\n        await handlePlaySonglist(info)\n        break\n      default: throw new Error('Unknown action: ' + action)\n    }\n  }\n}\n","sourceCodeStart":92,"sourceCodeEnd":114,"githubUrl":"https://github.com/lyswhut/lx-music-desktop/blob/9c364b482e5621a1d38b50e8610d2fb974457e6e/src/renderer/core/useApp/useDeeplink/useSonglistAction.js#L92-L114","documentation":"Songlist deep-link action dispatcher in useSonglistAction.js:110. The switch at lines 102-110 accepts only 'open' and 'play'; any other action token hits default and throws 'Unknown action: <token>'. This is the entry point returned by the module's default export.","triggerScenarios":"The deeplink router invokes the songlist hook with an action other than open/play — e.g. 'view', 'add', undefined, or an empty string from a malformed URL.","commonSituations":"Protocol version skew; a sender using a verb this build doesn't handle; an integration typo in the URL template.","solutions":["Confirm the action token is exactly 'open' or 'play'.","Catch at the deeplink router and surface unknown actions via useDialog().","Add new verbs to the switch when extending the protocol.","Log unknown actions to spot sender/receiver drift."],"exampleFix":"// before\n      default: throw new Error('Unknown action: ' + action)\n\n// after - explicit set + clear message\nconst SONGLIST_ACTIONS = new Set(['open', 'play'])\n// before dispatch:\nif (!SONGLIST_ACTIONS.has(action)) {\n  throw new Error(`Unknown songlist action: '${action}'. Expected 'open' or 'play'`)\n}","handlingStrategy":"validation","validationCode":"const SONGLIST_ACTIONS = new Set(['open', 'play'])\nif (!SONGLIST_ACTIONS.has(action)) {\n  showErrorDialog(`Unknown songlist action: ${action}`)\n  return\n}","typeGuard":"const SONGLIST_ACTIONS = ['open', 'play'] as const\ntype SonglistAction = typeof SONGLIST_ACTIONS[number]\nconst isSonglistAction = (a) => typeof a === 'string' && (SONGLIST_ACTIONS as readonly string[]).includes(a)","tryCatchPattern":"try {\n  await songlistDispatcher(action, info)\n} catch (e) {\n  errorDialog(e.message)\n}","preventionTips":["Share one constant for the songlist action set between router and dispatcher.","Log unknown actions to detect sender/receiver drift.","Always wrap the dispatcher at the router with useDialog() on failure."],"tags":["deeplink","validation","songlist","action-dispatch"],"backgroundTag":null,"analyzedSha":"9c364b482e5621a1d38b50e8610d2fb974457e6e","analyzedAt":"2026-08-12T15:14:48.244Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}