当前位置: 首页 > 知识库问答 >
问题:

如何正确实现异步/等待情况下的错误处理

元英朗
2023-03-14

我使用async/await ecma6标准,没有任何自定义库。

我现在不知道如何正确地捕捉和抛出错误。我有多个async/await函数,如果下面某个地方发生了严重错误,我希望将错误抛出到所有async函数的顶部,并停止函数的执行。

我试图抛出异常的异步/等待函数,并抓住它在目标函数,但我得到一个错误,在node.js:

    this.basicAuthLogin= async function(user)
{
    "use strict";
    const login = new Login(this.host, this.url, user, user.pw);

    //getSessionID throws error
    this.sessionID = getSessionID(result.request.response);
}

(节点:13964)未处理的PromisejectionWarning:未处理的promise拒绝(拒绝id:1):错误:getSessionID响应未定义(节点:13964)[DEP0018]弃用警告:未处理的promise拒绝已弃用。将来,未处理的promise拒绝将终止节点。具有非零退出代码的js进程。调试器已附加。

因此,我似乎不允许将异常抛出异步函数,甚至不允许在节点中promise的catch块中重新抛出异常。js?

那我怎么才能让它工作呢?我是否应该捕获异步函数中的错误,并在promise中返回错误,然后从异步函数中重试?

   this.basicAuthLogin= async function(user)
{
    "use strict";
    const login = new Login(this.host, this.url, user, user.pw);
   try{
    //getSessionID throws error
    this.sessionID = getSessionID(result.request.response);
   } catch(err) { return err;}
}

但这意味着在我的调用堆栈中,从第一个异步函数开始,每个函数都需要异步,我必须等待promise,即使我并不真正需要它。

我希望有人能启发我。

问候鲁维

编辑基本调用栈伪代码:

   async startTest[arr]{

    for (var i = 0; i < arr.length; i++)
    {
      try {
          await runStep(arr[i];
        } catch(err) { 
            console.log(err);
            break; 
        }
      }
    }

  async runStep(step)
  {
     try {
     var userIsValid = await validateUser(step.user);
     var req = buildRequest(step.request);
     var result = await sendRequest(req);
     var verify = verifyResult();
     } catch(err){ throw err;}
  }

  async validateUser(user)
  {
     //make checks
     //
     var result = await this.authenticate(parameter).catch(err => {throw err});
     userFound = true;
   }

  function authenticate(parameter) {
  //can throw async function
   basicAuthLogin(parameter).catch(err => {throw err};

   }

  function async basicAuthLogin(parameter()
  {
   try {
    //can throw  async function
      var result = await request(parameter);
      //can throw sync function
      this.sessionID = getSessionID(response);
      //can throw   sync function
      } catch(err) { throw err; }
   }

共有1个答案

华章横
2023-03-14

async/await的一个优点是,它们允许try/catch使用异步代码。

您的第一个basicAuthLogin函数是绝对正确的(前提是getSessionID是一个同步函数; 如果不是,您就缺少了一个 wait [您现在已经说过了])。使用basicAuthLogin的代码必须处理它将抛出的可能性(通过处理错误或允许它传播给负责处理错误的调用方)。因此,要么:

// In an `async` function
try {
    await this.basicAuthLogin(/*...*/);
} catch (e) {
    // Handle the fact something failed
}

// NOT in an `async` function:
this.basicAuthLogin(/*...*/)
    .catch(e => { /* Handle the fact something failed */ });

如果使用它的代码执行这两件事中的一件(或者让错误传播到执行这两件事中的一件的代码),您将不会得到“未处理的拒绝”错误。

在回答我关于getSessionID是否异步的问题时,您写道:

不,它不是异步的,它是一个简单的函数,抛出一个异常,我想捕获调用堆栈上的5或6层,但似乎不允许我这样做。

这里有一个这样做的例子(在我的例子中,我已经使basicAuthLogin实际上在getSessionID之前使用异步的东西,但这并不重要):

js prettyprint-override">const getSessionID = () => {
  throw new Error("Failed");
};
const somethingAsync = () => new Promise(resolve => {
  setTimeout(resolve, 100);
});
const basicAuthLogin = async function(user)
{
    "use strict";
    await somethingAsync();
    /*
    const login = new Login(this.host, this.url, user, user.pw);
    */

    //getSessionID throws error
    getSessionID();
};

const wrapper1 = async () => {
  await basicAuthLogin();
};
const wrapper2 = async () => {
  await wrapper1();
};
const wrapper3 = async () => {
  await wrapper2();
};

// Top-level caller
(async () => {
  try {
    await wrapper3();
  } catch (e) {
    console.log("Caught error: " + e.message);
  }
})();
 类似资料:
  • 我正在测试一个任务中的三个异步/等待函数(functionA、functionB、functionC)的条件序列,但是当我执行它时,声明第一个functionA不应该通过, 1-我没有得到预期的功能a失败消息 2-当任何函数没有传递时,我应该如何处理错误来停止序列?

  • 我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)

  • 我正在尝试为我的颤振应用程序编写一个测试。我为其编写测试的函数返回未来,因此我使用wait。 但是,只要使用任何WAIT语句,我就会得到MissingPluginException错误。 我尝试更改依赖项版本,但没有帮助。在GitHub上找不到与此相关的颤振问题或StackOverFlow。 预计工作正常。 获取错误: MissingPluginException(在channel plugins

  • 问题内容: 在我的程序中,我从另一个API模块调用了我的函数: 模块代码: 执行立即返回,但是,并因此包含请求对象和请求体- 样,不需要响应体。 我做错了什么?怎么修?正确的用法是什么,或仅与此处提到的Promise一起正确使用:为什么await对于节点请求模块不起作用?以下文章提到了可能的方法:在Node.js中掌握Async Await 。 问题答案: 您需要使用模块,而不是模块或。 对返回p

  • 我想使用异步并等待处理承诺。我想在下面的示例中使用这个方法: 在执行时,它给了我一个错误 错误: UnhandledPromiseRejectionWarning:未处理得承诺拒绝.这个错误可能是由于抛出一个没有catch块的异步函数内部,或者是由于拒绝了一个未用.catch()处理的承诺。(拒绝ID:3)

  • 问题内容: 假设我有某种游戏。我有一个buyItem函数,如下所示: 如果我对该路由进行垃圾邮件处理,直到扣除用户余额(第二次查询),则用户余额仍为正。 我尝试过的 问题是将在第一〜5项要求。因此,这也不起作用。 我们如何处理这种情况?如果重要的话,我正在使用Sails.JS框架。 问题答案: 通过该方法,Sails 1.0现在具有完整的事务支持。例: 更新资料 正如一些评论者所指出的,启用连接池