enwi / hueplusplus

A simple C++ library to control Philips Hue lights on Linux, MacOS, Windows, Espressif ESP32 SDK and Arduino. Full documentation at
https://enwi.github.io/hueplusplus/
GNU Lesser General Public License v3.0
53 stars 22 forks source link

Unhandled exception #86

Closed buelowp closed 1 year ago

buelowp commented 1 year ago

Describe the bug: I built a QT5 light bulb manager program which provides a way to control my outdoor Hue and LIFX bulbs using the same logic. This program runs s small set of schedules to turn these bulbs on/off but also on holidays provide some color. It's all local LAN control and most of the time just some version of white + brightness for simple on/off. Some holidays I add some color. This has been true for several years now using your library for the Hue bulbs without much trouble. Last night, for the first time, I hit the following exception. Note, the terminate on the throw doesn't seem to have gotten back to my application.

LinHttpHandler: Failed to connect socket: No route to host
LinHttpHandler: Failed to connect socket: No route to host
terminate called after throwing an instance of 'std::system_error'
  what():  LinHttpHandler: Failed to connect socket: No route to host
Aborted (core dumped)

To Reproduce: I have a timer set to a random value between 1 and 5 seconds running which calls

try {
    m_hue->at(index).setColorXY(hc.getXYB());
}
catch (std::exception &e)
{
    qWarning() << QDateTime::currentDateTime() << ": Hue did not respond correctly for bulb" << QString::fromStdString(m_hue->at(index).getName());
    qWarning() << e.what();
}

Where m_hue is a std::vector<hueplusplus::Light> *m_hue container for the Hue bulbs I am controlling and hc is a wrapper container of hueplusplus::XYBrightness.

I expect if you simply reboot the router while calling this API, you probably get the issue, though I don't have a simple way to test that right now.

Expected behavior: If this is an exception that can be handled, it should be forwarded through so the top level caller can handle it. Based on the print, it looks a if the library tries/fails and dies instead of attempting to send it to the parent.

Console log/Error message:

LinHttpHandler: Failed to connect socket: No route to host
LinHttpHandler: Failed to connect socket: No route to host
terminate called after throwing an instance of 'std::system_error'
  what():  LinHttpHandler: Failed to connect socket: No route to host
Aborted (core dumped)

Desktop (please complete the following information):

Additional context It looks as if my router hit some turbulence roughly when this happened, and network had some trouble. The logs show wifi issues, but the network stayed up (Hue bridge and this app are both on the wired network) and the first sign is about 90 seconds AFTER this, but it's probably related and the router logs are the router trying to recover from some fault at 3:00:00 AM.

I'm going to see if I can put some code in to handle this in the library later today, but am wondering if this can be more generic to the library itself.

If I can find it and handle it, I'll submit a patch if you choose to want it.

Jojo-1000 commented 1 year ago

This is strange, the exception should be propagated properly. Are you sure this is the spot that caused it? The exception might also be thrown as a result of trying to update the light state in a getter somewhere else. The library does not call terminate. There are a few reasons I can think of why it might terminate after the exception:

buelowp commented 1 year ago

Let me look, but that's the only use of the library while the code is running. Yes, it is multithreaded (Qt is by default). This is a QTimer callback, so I wonder if I should go looking there? The docs don't imply/state noexcept. You can see the try/catch in the code above, that's what's running when this exception occurred. There are no other library calls happening (from the hue light perspective, it's pretty simple on/off/change).

https://doc.qt.io/qt-6/exceptionsafety.html#exceptions-in-client-code

I didn't get a chance to work on this yesterday, and we are leaving on a holiday tomorrow, so this will probably go quiet until I return in 2 weeks. I think I know how to make it happen though, so if I get some free time today, I may just go unplug the switch everything is connected to and see what happens while running some test code. Have to wait for my wife to be done with work and for the kids to be done with homework tonight.