iflytek/astron-agent · error · Error
errMsg (dynamic; logged as…
Error message
errMsg (dynamic; logged as '录音open失败:'+errMsg+',isUserNotAllow:'+isUserNotAllow)
What it means
recorder-core's open() failure callback (failCall). When opening the recording resource fails, it logs '录音open失败:'+errMsg+',isUserNotAllow:'+isUserNotAllow, invokes the caller's False callback, and throws new Error(errMsg). errMsg is dynamic — permission denial, environment check failure, or the open being cancelled/interrupted by a close call.
Solutions
- Always pass a False callback to open() and handle (errMsg, isUserNotAllow) there; treat isUserNotAllow as a permissions UX problem
- Serve over HTTPS and verify Recorder.Support() before calling open
- Serialize open/close calls so close never lands mid-open (avoids open被取消/open被中断)
- Catch the thrown error around open() to keep the UI stable
Example fix
// before
rec.open(() => rec.start()); // no False handler; error thrown uncaught
// after
rec.open(
() => rec.start(),
(errMsg, isUserNotAllow) => {
console.error('open failed:', errMsg, 'userDenied:', isUserNotAllow);
showMicHelp(isUserNotAllow);
}
); Defensive patterns
Strategy: try-catch
Validate before calling
if (!Recorder.Support()) { showUnsupported(); return; } Type guard
function openSafe(rec, onOk) {
return new Promise((resolve, reject) => rec.open(resolve, (m, u) => reject({ m, u })));
} Try / catch
rec.open(
() => rec.start(),
(errMsg, isUserNotAllow) => {
if (isUserNotAllow) showPermissionHelp();
else console.error('录音open失败:', errMsg);
}
); Prevention
- Always supply both True and False callbacks to open()
- Avoid calling close() while open() is pending
- Run on HTTPS and verify browser support first
When it happens
Trigger: Recorder.open() failing for any reason: getUserMedia rejection (NotAllowedError → isUserNotAllow=true), NotReadableError/no device, envCheck returning a message ('不能录音:...'), or the library's sync lock detecting close-during-open ('open被取消'/'open被中断').
Common situations: Mic permission blocked; hardware mic in use by Zoom/Teams; http origin; rapid open→close toggling in UI causing the lock-cancel path to fire.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- msg (dynamic; logged as '无法录音:'+msg and shown via…
- msg (dynamic; logged as '无法录音:'+msg and shown via…
- code (dynamic; from e.name||e.message, logged as '请求录音权限错误')
- 未采集到录音
- 不应该出现pcm采样率 和需要的采样率 不一致
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/0216ce2ce564a511.
Report an issue: GitHub.
Appendix: source
Thrown at console/frontend/src/utils/record/recorder-core.js:754
return this;
} else {
return Recorder;
}
},
//打开录音资源True(),False(msg,isUserNotAllow),需要调用close。注意:此方法是异步的;一般使用时打开,用完立即关闭;可重复调用,可用来测试是否能录音
open: function (True, False) {
var This = this,
streamStore = This._streamStore();
True = True || NOOP;
var failCall = function (errMsg, isUserNotAllow) {
isUserNotAllow = !!isUserNotAllow;
This.CLog(
'录音open失败:' + errMsg + ',isUserNotAllow:' + isUserNotAllow,
1
);
False && False(errMsg, isUserNotAllow);
throw new Error(errMsg);
};
var ok = function () {
This.CLog('open ok id:' + This.id);
True();
This._SO = 0; //解除stop对open中的start调用的阻止
};
//同步锁
var Lock = streamStore.Sync;
var lockOpen = ++Lock.O,
lockClose = Lock.C;
This._O = This._O_ = lockOpen; //记住当前的open,如果变化了要阻止close,这里假定了新对象已取代当前对象并且不再使用
This._SO = This._S; //记住open过程中的stop,中途任何stop调用后都不能继续open中的start
var lockFail = function () {
//允许多次open,但不允许任何一次close,或者自身已经调用了关闭
if (lockClose != Lock.C || !This._O) {View on GitHub (pinned to 5e758547a8)