# Throw new Error in async method

**URL:** https://community.homey.app/t/throw-new-error-in-async-method/124207
**Category:** Developers
**Created:** [December 15, 2024, 9:25pm UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207 "2024-12-15T21:25:38Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![s\_dimaio](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/s_dimaio/32/78995_2.png) [@s\_dimaio](https://community.homey.app/u/s_dimaio)
#### Post date: [December 15, 2024, 9:25pm UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/1 "2024-12-15T21:25:38Z")

</div>

Hi, is there a way to use `throw new Error('my custom error');` inside an async method and still have it return the red alert with the custom error message?

Thanks in advance,

Simone

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 16, 2024, 5:52am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/2 "2024-12-16T05:52:39Z")

</div>

You have to show some context.

---

<div class="post-metadata">

### Author: ![s\_dimaio](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/s_dimaio/32/78995_2.png) [@s\_dimaio](https://community.homey.app/u/s_dimaio)
#### Post date: [December 16, 2024, 9:07pm UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/3 "2024-12-16T21:07:07Z")

</div>

Hi robert,  
i’m registering the capability ‘speaker\_playng’:

> this.registerCapabilityListener(‘speaker\_playing’, async (value) =\> { … }

I would like to insert a timer that throws an error if playback does not start after 5 seconds of pressing the play button:

> this.registerCapabilityListener(‘speaker\_playing’, async (value) =\> {  
> this.playbackTimer = this.homey.setTimeout(() =\> {  
> throw new Error(‘Playback Error!!!’);  
> }, 5000);  
> }

Unfortunately trying to throw a custom error from the (async) setTimeout method does not show the homey red alert with the error message.

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 17, 2024, 4:57am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/4 "2024-12-17T04:57:49Z")

</div>

This won’t work because using a timeout creates a separate context from the capability listener. The error is thrown inside the “timer context”, not the “capability listener context”.

I’m not sure how you determine if playback has started, but say that you use an (async) method `isPlaying()` for that.

In that case, you can use something like this (untested):

```auto
const delay = ms => new Promise(resolve => this.homey.setTimeout(resolve, ms));
const timeout = (promise, ms, err) => Promise.race([promise, delay(ms).then(() => throw Error(err))]);

this.registerCapabilityListener('speaker_playing', async (value) => {
  await timeout(this.isPlaying(), 5000, 'Playback Error!!!');
}

```

---

<div class="post-metadata">

### Author: ![ChrisG](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/chrisg/32/8825_2.png) [@ChrisG](https://community.homey.app/u/ChrisG)
#### Post date: [December 17, 2024, 5:31am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/5 "2024-12-17T05:31:32Z")

</div>

> [@robertklep](#):
>
> ```auto
> const timeout = (promise, ms, err) => Promise.race([promise, delay(ms).then(() => throw Error(err))]);
> 
> ```

This is the old “style” timeout, there is now an “official” one.

> **[callback - Homey - Homey Apps SDK v3](https://apps-sdk-v3.developer.homey.app/Homey.html#setTimeout)**
>
> Shortcut to ManagerI18n#\_\_

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 17, 2024, 5:33am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/6 "2024-12-17T05:33:47Z")

</div>

Not sure why you’re removing the line above it that uses that exact method 😜

---

<div class="post-metadata">

### Author: ![ChrisG](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/chrisg/32/8825_2.png) [@ChrisG](https://community.homey.app/u/ChrisG)
#### Post date: [December 17, 2024, 5:48am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/7 "2024-12-17T05:48:25Z")

</div>

It’s still early in the morning, but in my opinion it should read like this 🤔

```auto
this.registerCapabilityListener('speaker_playing', async (value) => {
  this.homey.setTimeout(this.isPlaying(), 5000, 'Playback Error!!!');
}

```

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 17, 2024, 5:58am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/8 "2024-12-17T05:58:01Z")

</div>

> [@ChrisG](#):
>
> It’s still early in the morning

Yes, it is. Read back on what the issue is that we’re trying to solve 😛

---

<div class="post-metadata">

### Author: ![ChrisG](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/chrisg/32/8825_2.png) [@ChrisG](https://community.homey.app/u/ChrisG)
#### Post date: [December 17, 2024, 6:24am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/9 "2024-12-17T06:24:47Z")

</div>

This is new, but isn’t the problem more with the Homey app?

BDW: I had to change all timeouts some time ago because the app no longer closed properly.

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 17, 2024, 6:38am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/10 "2024-12-17T06:38:09Z")

</div>

> [@ChrisG](#):
>
> This is new, but isn’t the problem more with the Homey app?

No.

> [@](#):
>
> BDW: I had to change all timeouts some time ago because the app no longer closed properly.

My proposed solution is using the SDK timeout implementation:

```auto
const delay = ms => new Promise(resolve => this.homey.setTimeout(resolve, ms));
                                             ^^^^^^^^^^^^^^^^^^^^^
const timeout = (promise, ms, err) => Promise.race([promise, delay(ms).then(() => throw Error(err))]);

```

---

<div class="post-metadata">

### Author: ![ChrisG](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/chrisg/32/8825_2.png) [@ChrisG](https://community.homey.app/u/ChrisG)
#### Post date: [December 17, 2024, 7:01am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/11 "2024-12-17T07:01:18Z")

</div>

Ok my mistake !!!

And what do we learn from this, first drink coffee and then read & write in the forum, then you don’t embarrass yourself…

Very big SORRY 🤦‍♂️…

---

<div class="post-metadata">

### Author: ![s\_dimaio](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/s_dimaio/32/78995_2.png) [@s\_dimaio](https://community.homey.app/u/s_dimaio)
#### Post date: [December 17, 2024, 8:54pm UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/12 "2024-12-17T20:54:51Z")

</div>

Thanks to both of you.

@robertkep I tried to use your code but without success. I’ll give you some more information on the structure of my class.

I’m working on device.js

in onOnit I define the variable for the timer:

> this.playbackTimer = null;

in registerCapabilityListener(‘speaker\_playing’) I set the timer as already indicated:

> this.registerCapabilityListener(‘speaker\_playing’, async (value) =\> {  
> this.playbackTimer = this.homey.setTimeout(() =\> {  
> …  
> throw new Error(‘Playback Error!!!’);  
> }, 5000);  
> }

in an async event that fires when the playback starts I clear the timer:

> this.on(‘playerChanged’, async (playerDetail) =\> {  
> …  
> this.homey.clearTimeout(this.playbackTimer);  
> }

In this way if the async event is not called or is called after 5 seconds from pressing the play button the timer callback fires, resets the player (and up to this point everything works) but does not return any error alert.

---

<div class="post-metadata">

### Author: ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)
#### Post date: [December 18, 2024, 5:58am UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/13 "2024-12-18T05:58:09Z")

</div>

I think you can use something like this:

```auto
// a new method that waits for an event until a timeout is reached
waitForEvent(event, timeout) {
  return new Promise((resolve, reject) => {
    this.once(event, resolve);
    this.homey.setTimeout(reject, timeout);
  });
}

// to use:
this.registerCapabilityListener('speaker_playing', async (value) => {
  try {
    const eventData = await this.waitForEvent('playerChanged', 5000);
  } catch(e) {
    throw Error('Playback Error!!!');
  }
});

```

---

<div class="post-metadata">

### Author: ![s\_dimaio](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/s_dimaio/32/78995_2.png) [@s\_dimaio](https://community.homey.app/u/s_dimaio)
#### Post date: [December 18, 2024, 9:10pm UTC](https://community.homey.app/t/throw-new-error-in-async-method/124207/14 "2024-12-18T21:10:33Z")

</div>

Thanks Robert! Works like a charm!
