[email protected] [2025-10-20 05:56]:

On Oct 18, 2025, at 2:11 AM, Kirill Miazine <[email protected]> wrote:

Greetings!

Yesterday I hit a case where some logging would throw RecursionError. After 
spending quite a bit of time hunting down the cause of the error, I doubled the 
recursion limit and went on.

Is logging RecursionError a normal behaviour to experience? Should I take it 
more seriously that just double the recursion limit?
In a word, "no, that's not normal". Without seeing the traceback I can't even 
say if this is Twisted's fault or your application's, so I can't say much more. But you 
should not be recursing so much that you get a RecursionError.

If it's a Twisted issue, please do let us know and file a bug.

it could certainly be an issue with my code, it wouldn't be the first time. exception look like  this, although it's a bit challenging to reproduce them. this one was obtained when I hit Ctrl-C.

[Failure instance: Traceback: <class 'RecursionError'>: maximum recursion depth exceeded
/home/monger/pyng/lib/pyng/master.py:428:_run_check
/home/monger/pyng/lib/pyng/master.py:379:_get_check
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:656:addErrback
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:533:addCallbacks
--- <exception caught here> ---
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:1074:_runCallbacks
/home/monger/pyng/lib/pyng/master.py:379:<lambda>
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:341:error
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:226:emit
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:87:__call__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:281:failure
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:226:emit
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:86:__call__
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:102:_errorLoggerForObserver
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:33:__init__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:142:__init__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:121:_namespaceFromCallingContext
]
[Failure instance: Traceback: <class 'RecursionError'>: maximum recursion depth exceeded
/home/monger/pyng/lib/pyng/master.py:428:_run_check
/home/monger/pyng/lib/pyng/master.py:379:_get_check
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:656:addErrback
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:533:addCallbacks
--- <exception caught here> ---
/usr/local/lib/python3.11/site-packages/twisted/internet/defer.py:1074:_runCallbacks
/home/monger/pyng/lib/pyng/master.py:379:<lambda>
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:341:error
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:226:emit
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:87:__call__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:281:failure
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:226:emit
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:86:__call__
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:102:_errorLoggerForObserver
/usr/local/lib/python3.11/site-packages/twisted/logger/_observer.py:33:__init__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:142:__init__
/usr/local/lib/python3.11/site-packages/twisted/logger/_logger.py:121:_namespaceFromCallingContext
]

line 379 referenced there looks like this

<code>

    376     def _get_check(self):
    377         d = self.checks_queue.get()
    378         d.addCallback(self._run_check)
    379         d.addErrback(lambda err: self.log.error('{failure}', failure=err))
    380         d.addErrback(print)
</code>

my theory thus far is that in _run_check there were errors, which triggered errback at line 379, and which again triggered error and I had lines above printed by errback on line 380.

I have identified three consecutive lines in my log, the first two are in _run_check.

<log>

2025-10-20T21:45:53+0200 [pyng.master.PyngMaster#info] Unable to format event {'check': <pyng.PING o bject at 0x294df13f3510>, 'log_logger': <Logger 'pyng.master.PyngMaster'>, 'log_level': <LogLevel=in fo>, 'log_namespace': 'pyng.master.PyngMaster', 'log_source': <pyng.master.PyngMaster object at 0x29 4df34c8090>, 'log_format': 'Ready to run {check.type} check "{check.desc}" [{check.id}]', 'log_time'
: 1760989553.4371765}: maximum recursion depth exceeded

2025-10-20T21:45:53+0200 [pyng.master.PyngMaster#info] Unable to format event {'check': <pyng.PING o bject at 0x294df13f3510>, 'log_logger': <Logger 'pyng.master.PyngMaster'>, 'log_level': <LogLevel=in fo>, 'log_namespace': 'pyng.master.PyngMaster', 'log_source': <pyng.master.PyngMaster object at 0x29 4df34c8090>, 'log_format': 'No remote runners for {check.type} check "{check.desc}" [{check.id}]', '
log_time': 1760989553.437236}: maximum recursion depth exceeded

2025-10-20T21:45:53+0200 [pyng.master.PyngMaster#info] Unable to format event {'check': <pyng.PING o bject at 0x294df13f3510>, 'delay': 60, 'log_logger': <Logger 'pyng.master.PyngMaster'>, 'log_level':  <LogLevel=info>, 'log_namespace': 'pyng.master.PyngMaster', 'log_source': <pyng.master.PyngMaster o bject at 0x294df34c8090>, 'log_format': 'Schedule {check.type} check "{check.desc}" [{check.id}] to run in {delay} seconds', 'log_time': 1760989553.437282}: maximum recursion depth exceeded while call
ing a Python object

</log>

now for the code. the first log message is printed out immediately after the start of running of the function

<code>

    def _run_check(self, check):
        self.log.info(
            'Ready to run {check.type} check "{check.desc}" [{check.id}]',
            check=check,
        )
</code>

the next one is also failry simple, still in _run_check, it just notifies that there are no AMP runners available to run the task and re-schedules it

<code>

        if self.force_remote and runner is None:
            self.log.info(
                'No remote runners for {check.type} check "{check.desc}" [{check.id}]',
                check=check,
            )

        del self.running[check]
        self._reschedule_check(check, check.interval)
        return self._get_check()

</code>

and the last log line is related to when re-scheduling takes place

<code>

    def _reschedule_check(self, check, delay=60):
        if check in self.scheduled:
            self.log.error(
                '{check.type} check "{check.desc}" [{check.id}] already scheduled',
                check=check,
            )
            return

        def _enqueue():
            del self.scheduled[check]
            self.checks_queue.put(check)
        self.scheduled[check] = reactor.callLater(delay, _enqueue)
        self.log.info(
            'Schedule {check.type} check "{check.desc}" [{check.id}] to run in {delay} seconds',
            check=check, delay=delay,
        )
</code>

this looks failry simple.

I have only seen this kind of error when AMP remotes disappear and I have some connecting and re-connecting logic, where there could be some recursion snafu.



-g

_______________________________________________
Twisted mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/twisted.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/PQVMO2WSHVR3A6VR4CG3JRSDDIDNIW44/
Code of Conduct: https://twisted.org/conduct
_______________________________________________
Twisted mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/twisted.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/TUDZYEVHBLRBPSKMYBWPJ6QNZOS2X43G/
Code of Conduct: https://twisted.org/conduct

Reply via email to