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

  1. Always pass a False callback to open() and handle (errMsg, isUserNotAllow) there; treat isUserNotAllow as a permissions UX problem
  2. Serve over HTTPS and verify Recorder.Support() before calling open
  3. Serialize open/close calls so close never lands mid-open (avoids open被取消/open被中断)
  4. 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

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


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)