# Promise.prototype.uncaught

**URL:** <https://es.discourse.group/t/promise-prototype-uncaught/507>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [October 21, 2020, 2:23am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507 "2020-10-21T02:23:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 21, 2020, 2:23am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/1 "2020-10-21T02:23:27Z")

</div>

As [https://tc39.es/ecma262/#sec-promise.prototype.catch](https://tc39.es/ecma262/#sec-promise.prototype.catch) stated that, `Promise.prototype.catch` support for catching specified rejection from a Promise. Nevertheless, developers always miss a method, which I have named as `Prototype.prototype.uncaught` to handle default errors not caught by any handlers.

Similarly, Node has supported **unhandledRejection** for developers to catch any uncaught error from a Promise.

Such a method can help developers to set up a default error handler for all promises.

---

<div class="post-metadata">

**Author:** ![Jonas\_Wilms](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jonas_wilms/32/189_2.png) [@Jonas\_Wilms](https://es.discourse.group/u/Jonas_Wilms)\
**Post date:** [October 23, 2020, 3:57pm UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/2 "2020-10-23T15:57:33Z")

</div>

Some questions I have with this proposal:

(1) Why is it supposed to be placed on the Prototype, if it attaches a handler onto all Promises (as the unhandledRejection event handler does)?

(2) Does handling an error thrown in an async function (rejecting a Promise) differ from throwing in a sync function? Can't the handler handle the general case?

(3) What happens after the handler executed? Does execution end? Or can the handler decide? What happens if a Promise gets rejected (without a handler attached) inside the handler itself?

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 1:12am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/3 "2020-10-26T01:12:42Z")

</div>

1. It depends on whether you want to handle uncaught situation in a middle state or in the end? If in the middle, a prototype method is proper, while a global method is proper in the end.

2. Take node implementation as an example, `unhandledRejection` will also be fired in two situations:

- Use `Promise.reject` directly:

- Two embedded async / await function:

1. My assume is like the following snippet:

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [October 26, 2020, 1:31am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/4 "2020-10-26T01:31:26Z")

</div>

Can you maybe give an example of how you envision this `uncaught` method to be used? It's not quite clear what you are after.

However, it sounds like you are looking to find whether a specific promise got rejected and the error did not get handled anywhere else. This is not possible. Handlers do not "report back" to the promise whether an error got handled or not. Any `.catch()`, `.then()` (and by extension `await`) call simply forwards errors that didn't get handled and will reject _another_ promise with it. The internal state of the original promise is marked as "handled". The `unhandeldRejection` event only fires for the promises that are the end of a chain.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 1:49am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/5 "2020-10-26T01:49:34Z")

</div>

@bergus Two situations:

1. If we want to check whether a Promise chain has uncaught rejected result in the middle of processes, we can use `Promise.prototype.uncaught`:

2. If we want to check finally, wen can use `Promise.uncaught`:

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 1:53am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/6 "2020-10-26T01:53:32Z")

</div>

node does indeed fire the event on `Promise.reject()` by itself. I’m not sure i understand your second example.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 1:54am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/7 "2020-10-26T01:54:46Z")

</div>

> [@aleen42](#):
>
> ```js
> new Promise((ignore, reject) => reject(1)); // fire
> 
> ```

@ljharb It it as same as `Promise.reject(1)` to some extent. To make it simple

```js
Promise.reject(1); // fire
Promise.reject(1).catch(r => r > 1); // not fired
Promise.reject(1).then(() => {}, r => r > 1); // not fired

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 2:08am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/8 "2020-10-26T02:08:01Z")

</div>

Sure, in both of those “not fired” cases, the promise is caught/handled. The two catch handlers never throw in those examples, so those promises can never be uncaught, which is why it’s not fired.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 2:09am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/9 "2020-10-26T02:09:37Z")

</div>

Exactly. So what can I do before making it as a official proposal?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 2:21am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/10 "2020-10-26T02:21:16Z")

</div>

My understanding of the use case of the global uncaught rejection handlers is for promises you _forgot_ to handle. If you remembered to do `.uncaught`, why not just do `.catch`?

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 2:25am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/11 "2020-10-26T02:25:16Z")

</div>

For instance, we want a default handler to handle any other exceptions we may not know, especially when integrating Promise with XMLHttpRequest:

```javascript
const catchCode = (expected, cb) =>
    code => code !== expected ? Promise.reject(code) : cb();

Promise.reject(anyCode)
    .catch(catchCode(1, () => console.log('catch 1')))
    .catch(catchCode(2, () => console.log('catch 2')))
    .uncaught(() => console.log('default handler for any other code'));

```

Besides, it is better for code reading than:

```javascript
Promise.reject(anyCode)
    .catch(catchCode(1, () => console.log('catch 1')))
    .catch(catchCode(2, () => console.log('catch 2')))
    .catch(() => console.log('default handler for any other code'));

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 2:36am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/12 "2020-10-26T02:36:08Z")

</div>

That seems like “just .catch without using your catchCode abstraction”?

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 2:41am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/13 "2020-10-26T02:41:28Z")

</div>

In my opinion, `catch` is for exact exceptions, while `uncaught` for unknown or unhandled exceptions. And so far as you said, we just only need a global function for promises we forgot to handle.

```javascript
Promise.uncaught(
    Promise.reject(anyCode),
    () => console.log('default handler for any other code')
)
    .catch(catchCode(1, () => console.log('catch 1')))
    .catch(catchCode(2, () => console.log('catch 2')))    

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 3:55am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/14 "2020-10-26T03:55:54Z")

</div>

currently catch is for any rejection (rejections aren’t necessarily exceptions), including unknown ones.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [October 26, 2020, 4:10am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/15 "2020-10-26T04:10:06Z")

</div>

In your first situation, it seems using standard `.catch()` would have the exact same result as you desire.

For your second situation, [you can write your own `Promise.uncaught`](https://stackoverflow.com/a/57792542/1048572), but it is pretty hacky and will never work in the middle of a chain, especially not with `uncaught(somePromise, handler).then(ignore)`.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 4:21am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/16 "2020-10-26T04:21:26Z")

</div>

So is it necessary to make it as a proposal to add such a method?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [October 26, 2020, 4:55am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/17 "2020-10-26T04:55:31Z")

</div>

It would be necessary, but I don't see why it would be beneficial to add such a method, since `.catch` already serves this purpose. In other words, while it's perfectly valid for you to choose to see `catch` as "for exact exceptions", that's not how it's defined nor how it's commonly used.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 26, 2020, 6:18am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/18 "2020-10-26T06:18:08Z")

</div>

Like what @bergus said above, standard `Promise.prototype.catch` can handle the first situation, except detecting unhandled Promise like [https://stackoverflow.com/a/57792542](https://stackoverflow.com/a/57792542).

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [October 27, 2020, 10:12am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/19 "2020-10-27T10:12:57Z")

</div>

I have created [a draft proposal](https://github.com/aleen42/proposal-promise-uncaught), and feel free to discuss it.

---

<div class="post-metadata">

**Author:** ![aleen42](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aleen42/32/461_2.png) [@aleen42](https://es.discourse.group/u/aleen42)\
**Post date:** [April 25, 2021, 8:21am UTC](https://es.discourse.group/t/promise-prototype-uncaught/507/21 "2021-04-25T08:21:01Z")

</div>

If I want to register a global default error handler for any promises, I need to override the method `Promise.prototype.catch`? In such a situation, if I don't want to handle it in one catching block, I need to reject it again to give to default handler?

```javascript
const fn = Promise.prototype.catch;
Object.assign(Promise.prototype, {
    catch() {
        if (this instanceof UnhandledPromise) {
            // default handling
        } else {
            return fn.apply(this, arguments);
        }
    }
});

doSomething().catch(err => {
    if (err.code === 1) {
        // handler error code 1 here 
    } else {
        // give to a default handler
        return Promise.reject(new UnhandledPromise(err));
    }
})

```

[Next page](https://es.discourse.group/t/promise-prototype-uncaught/507.md?page=2)
