{"record":{"id":"90d2805c8b738d09","repo":"iflytek/astron-agent","slug":"msg-dynamic-logged-as-msg-and-shown-via-message-info-record","errorCode":null,"errorMessage":"msg (dynamic; logged as '无法录音:'+msg and shown via message.info)","messagePattern":"msg \\(dynamic; logged as '无法录音:'\\+msg and shown via message\\.info\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"console/frontend/src/utils/record/record.js","lineNumber":331,"sourceCode":"\n        _this.rec.open(\n          () => {\n            //打开麦克风授权获得相关资源\n            clearTimeout(t);\n            _this.rec.start(); //开始录音\n\n            _this.RealTimeSendTryReset(); //重置环境，开始录音时必须调用一次\n            resolve('success');\n          },\n          function (msg, isUserNotAllow) {\n            clearTimeout(t);\n            message.info(msg);\n            console.error(\n              (isUserNotAllow ? 'UserNotAllow，' : '') + '无法录音:' + msg,\n              1\n            );\n            reject(msg);\n            throw new Error(msg);\n          }\n        );\n      });\n    },\n\n    sendData: function (audioData) {\n      // console.log(\"audioData=>\", audioData)\n      this.ws.send(audioData);\n      this.status = 1;\n    },\n  };\n}\nexport default Media;\n","sourceCodeStart":313,"sourceCodeEnd":345,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/frontend/src/utils/record/record.js#L313-L345","documentation":"Same dynamic open-failure error as in media.js, thrown from record.js's open() promise handler. When the microphone cannot be opened, the wrapper shows message.info(msg), logs '无法录音:'+msg, rejects the promise with msg, and throws new Error(msg). msg is the underlying recorder-core reason string.","triggerScenarios":"Recorder.open failing due to denied mic permission (UserNotAllow), missing/inaccessible audio input, insecure origin (non-HTTPS), 'open被取消'/'open被中断' from the library's open/close lock, or envCheck failure.","commonSituations":"User denies the permission prompt; another app holds the mic exclusively; page served over http in production; calling open after close triggered the lock-cancel path.","solutions":["Inspect the caught msg: UserNotAllow → prompt user to reset site permissions; open被取消/中断 → fix open/close call ordering in your UI logic","Ensure HTTPS or localhost origin","Guard with Recorder.Support() / navigator.mediaDevices existence check before opening","Handle the promise rejection so the thrown error does not surface as an uncaught exception"],"exampleFix":"// before\nrecord.open(() => start()).catch((m) => { throw m; });\n// after\nrecord.open(\n  () => start(),\n  (msg, isUserNotAllow) => {\n    isUserNotAllow\n      ? message.warning('请允许麦克风权限后重试')\n      : message.error('无法录音: ' + msg);\n  }\n).catch(() => {});","handlingStrategy":"try-catch","validationCode":"if (!navigator.mediaDevices?.getUserMedia) {\n  message.error('录音不可用：需要 HTTPS 环境');\n  return;\n}","typeGuard":"function micAvailable() { return !!navigator.mediaDevices?.getUserMedia; }","tryCatchPattern":"record.open(\n  () => start(),\n  (msg, isUserNotAllow) => isUserNotAllow\n    ? message.warning('请允许麦克风权限')\n    : message.error('无法录音: ' + msg)\n);","preventionTips":["Handle the False callback instead of relying on the throw","Serialize open/close calls","Prompt users to reset denied permissions"],"tags":["audio","microphone","permissions","browser"],"backgroundTag":"permission-denied","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}