Crash caused by timeout -> where to look?

I get a lot of the following crash reports from my app, but I can’t figure out what the cause is. Does anyone have an idea where to look for the error?

Note: this e-mail is sent because an unhandledRejection occurred in your app. Make sure to catch all errors, this might crash your app in the future. Stack trace attached below:

  Error: Timeout after 5000ms
    at Function.timeout (/node_modules/homey-api/lib/Util.js:57:26)
    at HomeyAPIApp.call (/node_modules/homey-api/lib/HomeyAPI/HomeyAPIV2.js:359:28)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ManagerDevices.value (/node_modules/homey-api/lib/HomeyAPI/HomeyAPIV2/Manager.js:261:24)

Are you using App API calls?

Yes, I both use api-calls through

this.homey.api.getApiApp(‘xxxxx’)

and

new HomeyAPIApp({
homey: this.homey
});

It looks like the issue is caused by that, the other app apparently doesn’t respond quickly enough.

Yeah, that sounds logical, but the problem is that I for testing replaced every single API call with a throw(new Error(“test error”)) and it turned out that all of these were caught by my crash protection code… Thus I still have no idea why there is an uncaught crash within these API calls ???

I see from the code that the crash is reported from

/node_modules/homey-api/lib/HomeyAPI/HomeyAPIV2/Manager.js:261:24
248:           if (this.homey.isConnected() && $socket === true) {
249:              result = await Util.timeout(new Promise((resolve, reject) => {
250:                this.homey.__ioNamespace.emit('api', {
251:                  args,
252:                  operation: operationId,
253:                  uri: this.uri,
254:                }, (error, result) => {
255:                  if (error) return reject(new HomeyAPIError({ error }));
256:                  return resolve(result);
257:                });
258:              }), $timeout);
259:            } else {
260:              // Get from HTTP
261:              result = await this.homey.call({
262:                $timeout,
263:                headers,
264:                body,
265:                path: `/api/manager/${this.id}${path}`,
266:                method: operation.method,
267:              });
268:            }

It appears from line 249 that a Promise should have been rejected and returned in the code for line 261, but instead it doesn’t seem to be any exception handling here… So I guess this is a problem with the Athom node module code.

Or it assumes that any exceptions are handled higher up, like in your code.

But then, why is it not sent to my code? I mean, I would have seen a crash myself when I replaced all api-calls with throw(new Error(“xxx”)), but I didn’t because everything was caught by my exception handlers…

As it is a timeout I assume Homey is heavily loaded. Could it be that a function in my own code is called multiple times without having finished its last run and as such overwrite some state and then Homey loses track of the calling function?

Losing track (or rather: context) could happen if callbacks are mixed with promises.

This error was really hard to find but I think I nailed it now.

So I thought I was smart to do some “prefetching” as such:


promiseDevice = this.homeyApi.devices.getDevice({ id: deviceId });
....lots of code....
try {
    let device = await promiseDevice;
} catch(err) {
    ...
}

but apparently, I had a conditional return statement within the ...lots of code... block.
Not so sure it was so smart after all :stuck_out_tongue_closed_eyes:

1 Like