There are a few things I would do:
First, switch to using UDP.receivePacket instead of parsePacket and read. ReceivePacket directly returns an error even when there’s no data, which makes it much better for detecting when a problem has occurred.
Second, if you use UDP listeners you basically have to use SYSTEM_THREAD(ENABLED) and take note of when WiFi becomes disconnected (WiFi.ready() returns false) from loop.
The reason is that when WiFi disconnects, all of the listeners are removed, and are not re-created for you. So when you detect that you disconnect, set a flag and then when you reconnect, do your UDP.begin() calls again.
I find if I do those two things it’s reliable.