Skip to content

Bot hangs (zombie state) instead of crashing on TimeoutException in updates.getChannelDifference #1750

Description

@xcgu

Describe the bug
When a TimeoutException occurs during updates.getChannelDifference, the background update-polling fiber crashes and stops fetching new updates entirely.
However, the main EventLoop and outbound connections remain alive (the bot can still catch the exception and send error messages to a Telegram chat). The core issue is that MadelineProto does not automatically recover or restart the update loop after this specific timeout, leaving the bot deaf to new updates until manually restarted via $this->restart().

To Reproduce
It happens randomly due to network timeouts when the bot tries to fetch updates via updates.getChannelDifference.

Expected behavior
MadelineProto should catch the timeout internally and retry fetching updates, or automatically restart the polling fiber, rather than letting the update loop die while the rest of the bot stays alive.

Stack trace

Surfaced: Amp\TimeoutException: Timeout while waiting for updates.getChannelDifference (Enable assertions for a backtrace of the Amp\TimeoutCancellation creation) in /bot/vendor/amphp/amp/src/TimeoutCancellation.php:36
Stack trace:
#0 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#1 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(525): Fiber->resume()
#3 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#4 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#5 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#6 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#7 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#8 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#9 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#10 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#11 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#12 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#13 {main}

Next Amp\CancelledException: The operation was cancelled in /bot/vendor/amphp/amp/src/Internal/Cancellable.php:57
Stack trace:
#0 /bot/vendor/amphp/amp/src/Internal/Cancellable.php(48): Amp\Internal\Cancellable->getException()
#1 /bot/vendor/amphp/amp/src/TimeoutCancellation.php(36): Amp\Internal\Cancellable->cancel()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#3 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#4 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(525): Fiber->resume()
#5 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#6 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#7 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#8 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#9 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#10 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#11 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#12 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#13 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#14 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#15 {main}

Surfaced: Amp\TimeoutException: Timeout while waiting for updates.getChannelDifference (Enable assertions for a backtrace of the Amp\TimeoutCancellation creation) in /bot/vendor/amphp/amp/src/TimeoutCancellation.php:36
Stack trace:
#0 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#1 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(65): Fiber->resume()
#3 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(453): Revolt\EventLoop\Internal\DriverSuspension::{closure:Revolt\EventLoop\Internal\DriverSuspension::resume():62}()
#4 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(595): Revolt\EventLoop\Internal\AbstractDriver->invokeMicrotasks()
#5 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#6 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(530): Fiber->start()
#7 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#8 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#9 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#10 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#11 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#12 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#13 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#14 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#15 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#16 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#17 {main}

Next Amp\CancelledException: The operation was cancelled in /bot/vendor/amphp/amp/src/Internal/Cancellable.php:57
Stack trace:
#0 /bot/vendor/amphp/amp/src/Internal/Cancellable.php(48): Amp\Internal\Cancellable->getException()
#1 /bot/vendor/amphp/amp/src/TimeoutCancellation.php(36): Amp\Internal\Cancellable->cancel()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#3 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#4 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(65): Fiber->resume()
#5 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(453): Revolt\EventLoop\Internal\DriverSuspension::{closure:Revolt\EventLoop\Internal\DriverSuspension::resume():62}()
#6 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(595): Revolt\EventLoop\Internal\AbstractDriver->invokeMicrotasks()
#7 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#8 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(530): Fiber->start()
#9 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#10 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#11 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#12 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#13 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#14 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#15 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#16 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#17 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#18 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#19 {main}

Surfaced: Amp\TimeoutException: Timeout while waiting for updates.getDifference (Enable assertions for a backtrace of the Amp\TimeoutCancellation creation) in /bot/vendor/amphp/amp/src/TimeoutCancellation.php:36
Stack trace:
#0 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#1 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(525): Fiber->resume()
#3 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#4 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#5 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#6 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#7 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#8 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#9 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#10 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#11 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#12 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#13 {main}

Next Amp\CancelledException: The operation was cancelled in /bot/vendor/amphp/amp/src/Internal/Cancellable.php:57
Stack trace:
#0 /bot/vendor/amphp/amp/src/Internal/Cancellable.php(48): Amp\Internal\Cancellable->getException()
#1 /bot/vendor/amphp/amp/src/TimeoutCancellation.php(36): Amp\Internal\Cancellable->cancel()
#2 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(629): Amp\TimeoutCancellation::{closure:Amp\TimeoutCancellation::__construct():29}()
#3 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createCallbackFiber():593}()
#4 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(525): Fiber->resume()
#5 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(586): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()
#6 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::createLoopFiber():566}()
#7 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(96): Fiber->resume()
#8 /bot/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php(119): Revolt\EventLoop\Internal\AbstractDriver->{closure:Revolt\EventLoop\Internal\AbstractDriver::__construct():90}()
#9 /bot/vendor/amphp/amp/src/Future.php(252): Revolt\EventLoop\Internal\DriverSuspension->suspend()
#10 /bot/vendor/danog/madelineproto/src/Wrappers/Loop.php(107): Amp\Future->await()
#11 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(86): danog\MadelineProto\MTProto->loop()
#12 /bot/vendor/danog/madelineproto/src/AbstractAPI.php(67): danog\MadelineProto\AbstractAPI->startAndLoopLogic()
#13 /bot/vendor/danog/madelineproto/src/EventHandler.php(180): danog\MadelineProto\AbstractAPI->startAndLoopInternal()
#14 /bot/index.php(42): danog\MadelineProto\EventHandler::startAndLoopBot()
#15 {main}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions