Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improper handling of Python C-API exceptions #1708

Open
4 of 7 tasks
Mrigank11 opened this issue Feb 9, 2024 · 0 comments
Open
4 of 7 tasks

Improper handling of Python C-API exceptions #1708

Mrigank11 opened this issue Feb 9, 2024 · 0 comments
Labels
investigate further It's unclear what the issue is at this time but there is enough interest to look into it

Comments

@Mrigank11
Copy link

Mrigank11 commented Feb 9, 2024

Description

The library calls Python APIs (Logger.log specifically) without checking whether the Python error indicator was set.

result = PyObject_CallMethod(h->logger, "log", "issss",

As Python docs,

If the error is not handled or carefully propagated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways.

Consider a case where Logger.log raises an exception, thus, setting the python error indicator. In the next log_cb invocation by librdkafka, this library would again call Logger.log without handling the previous error. Because of this, method calls returns a misleading SystemError which is difficult to catch in a python application.

How to reproduce

We see this issue consistently when SIGINT is sent to a process which is polling the Consumer. Logger.log raises a KeyboardInterrupt which isn't handled before calling Logger.log again. We can't share our proprietary application so here's a minimal reproducer using a mock Logger class to easily reproduce the issue (we see the issue with the default Logger class):

from confluent_kafka import Consumer

bootstrap_servers = "<bootstrap servers>"
consumer_config = {
    'bootstrap.servers': bootstrap_servers,
    'group.id': 'NONE',
    'debug': 'all',
}

print("creating consumer")

class Logger:
    """
    Mock Logger class to easily reproduce the issue
    """
    def log(self, *args, **kwargs):
        raise KeyboardInterrupt

logger = Logger()

consumer = Consumer(consumer_config, logger=logger)
print("consumer created")

consumer.subscribe(["some_topic"])

while True:
    print("polling")
    r = consumer.poll(2)

Running this would show this:

[nix-shell:/codemill/krishan/maestro-api]$ python cf_gh_issue.py |& head -100
creating consumer
consumer created
polling
Traceback (most recent call last):
  File "/codemill/krishan/maestro-api/cf_gh_issue.py", line 21, in log
    raise KeyboardInterrupt
KeyboardInterrupt

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/codemill/krishan/maestro-api/cf_gh_issue.py", line 21, in log
    raise KeyboardInterrupt
SystemError: <class 'KeyboardInterrupt'> returned a result with an exception set

This SystemError is misleading.

Checklist

Please provide the following information:

  • confluent-kafka-python and librdkafka version: 2.3.0
  • Apache Kafka broker version: 3.0.0
  • Client configuration: debug=all
  • Operating system: Red Hat Enterprise Linux 8.9
  • Provide client logs (with 'debug': '..' as necessary)
  • Provide broker log excerpts
  • Critical issue
@pranavrth pranavrth added the investigate further It's unclear what the issue is at this time but there is enough interest to look into it label Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigate further It's unclear what the issue is at this time but there is enough interest to look into it
Projects
None yet
Development

No branches or pull requests

2 participants