Promise fails to catch

huangapple go评论71阅读模式
英文:

Promise fails to catch

问题

I'm trying to understand error catching in promises and I'm not getting something. I've read up on it and from everything I've seen it should be working so I'm not sure what I'm missing. I have a sample method that for now I'm just throwing an error (to simulate when it may actually throw an error later). That method looks like this:

我试图理解Promises中的错误捕获,但我不明白其中的一些内容。我已经查阅了相关资料,根据我所看到的一切,它应该正常工作,所以我不确定我漏掉了什么。我有一个示例方法,目前我只是抛出一个错误(模拟以后可能会抛出错误的情况)。该方法如下:

DeleteProject(id: string, customerId: string): Promise<void> {
throw new Error('test error');
}

I'm then calling this in my code like this:

然后我在我的代码中这样调用它:

projectService.DeleteProject(state.FocusedProject.ID, state.FocusedProject.CustomerID)
.then(() => {
...stuff when it works...
})
.catch(error => {
console.log('caught you');
HandleError(error, 'Delete Project');
});

When this method does not throw an error the code in the then block gets called and all works fine. However, when I throw the error it gives me an unhandled execution error and the catch block is never called.

当这个方法不抛出错误时,then 块中的代码会被调用,一切都正常工作。但是,当我抛出错误时,它会给我一个未处理的执行错误,catch 块从未被调用。

From everything I've read, throwing an error inside of that function should automatically be caught and return the rejected promise right? If so then when is it not being caught?

根据我所了解的一切,在该函数内部抛出错误应该自动被捕获并返回拒绝的 promise,对吗?如果是这样,那么它为什么没有被捕获呢?

I'm sure I'm missing something here but I can't see what it is. I basically want the catch block to say 'if anything goes wrong in the method I called then do this'.

我确信我在这里漏掉了什么,但我看不出是什么。基本上,我希望 catch 块能够说'如果在我调用的方法中发生了任何问题,那么执行这个操作'。

英文:

I'm trying to understand error catching in promises and I'm not getting something. I've read up on it and from everything I've seen it should be working so I'm not sure what I'm missing. I have a sample method that for now I'm just throwing an error (to simulate when it may actually throw an error later). That method looks like this:

DeleteProject(id: string, customerId: string): Promise&lt;void&gt; {
    throw new Error(&#39;test error&#39;);
}

I'm then calling this in my code like this:

projectService.DeleteProject(state.FocusedProject.ID, state.FocusedProject.CustomerID)
    .then(() =&gt; {
        ...stuff when it works...
    })
    .catch(error =&gt; {
        console.log(&#39;caught you&#39;);
        HandleError(error, &#39;Delete Project&#39;);
    });

When this method does not throw an error the code in the then block gets called and all works fine. However, when I throw the error it gives me an unhandled execution error and the catch block is never called.

From everything I've read, throwing an error inside of that function should automatically be caught and return the rejected promise right? If so then when is it not being caught?

I'm sure I'm missing something here but I can't see what it is. I basically want the catch block to say 'if anything goes wrong in the method I called then do this'.

答案1

得分: 2

正如评论中所述,DeleteProject 标记为返回 Promise&lt;void&gt;,但没有标记为 async。像所有非 async 函数一样,它可以抛出错误,这些错误然后在 try/catch 块的一部分而不是 Promise.thenPromise.catch 的调用中捕获。这是必须分别处理的两个单独的错误通道。

Promise 机制将使用 throw 抛出的错误转换为拒绝的 Promises,但仅在以下情况下:

  1. 在 [new Promise 构造函数中](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#parameters "Any errors thrown in the executor will cause the promise to be rejected")
  2. 在传递给 [Promise.thenPromise.catch 的函数中](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#return_value "throws an error: p gets rejected with the thrown error as its value")
  3. 在 [async 函数中](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#return_value "A Promise which will be resolved [...], or rejected with an exception thrown from, or uncaught within, the async function")

除非在同步处理错误方面有实际价值,否则在这里使用 return Promise.reject(new Error(...)) 风格可能比 throw new Error(...) 更好。要求函数调用者处理两种错误风格(同步和异步)是非典型的,而且可能 DeleteProject 与服务器通信时可能异步返回错误。这意味着调用者只需处理一个错误通道,而不管错误是同步还是异步。

在 OP(sfaust)的后续评论中,他们暗示他们将需要处理两种类型的错误(来自服务器的异步错误和来自无效输入的同步错误)。区分开发时错误和运行时错误是一个合理的原因,但如果是这样,非常重要的是记录该函数(DeleteProject 在这里)可以发出两种类型的错误的事实。请记住,即使可以同步检测或捕获错误,对于函数的调用者,您仍然可以决定提供什么样的外部 API:对于手动编写的返回 Promise 的函数(即没有 async 的函数),即使这意味着将函数包装在 try/catch 块中并使用特定的 Error 子类来指示对函数的无效调用,仍然可能更可预测发送所有错误通过拒绝的 promise。

英文:

As in the comments, DeleteProject is marked as returning a Promise&lt;void&gt; but it is not marked async. Like all non-async functions, it can throw errors, which are then caught as part of a try/catch block instead of a call to Promise.then or Promise.catch. These are two separate error channels that have to be handled separately.

Promise machinery will convert errors thrown with throw into rejected Promises, but only in these situations:

  1. In a [new Promise constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#parameters "Any errors thrown in the executor will cause the promise to be rejected")
  2. In a function passed to [Promise.then or Promise.catch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#return_value "throws an error: p gets rejected with the thrown error as its value")
  3. In an [async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#return_value "A Promise which will be resolved [...], or rejected with an exception thrown from, or uncaught within, the async function")

Unless there's real value in handling the error synchronously, it might be better to use the return Promise.reject(new Error(...)) style here instead of throw new Error(...). It is atypical to require function caller to handle both styles of error (synchronous and asynchronous), and presumably it is possible for DeleteProject to return an error asynchronously if it communicates with the server. This would mean that callers only have one error channel to handle regardless of whether the error is synchronous or asynchronous.

In a follow-up comment from the OP (sfaust), they suggest that they will need to handle both types (asynchronous from the server, and synchronous from invalid input). Distinguishing between development-time error and runtime errors is a rational reason, but if so it may be very important to document the fact that the function (DeleteProject here) can issue both types of error. Remember, though, that even when errors can be detected or caught synchronously, it's still up to you what kind of external API you provide to callers of your function: For manually-written promise-returning functions (i.e. without async), it may still be more predictable to send all errors through a rejected promise, even if it means wrapping the function in a try/catch block and using a particular subclass of Error to indicate invalid calls to the function.

huangapple
  • 本文由 发表于 2023年5月26日 01:20:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76334835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定