noirello / bonsai

Simple Python 3 module for LDAP, using libldap2 and winldap C libraries.
MIT License
117 stars 33 forks source link

ValueError('Invalid file descriptor: -1') raised when sever not reachable #27

Closed garyvdm closed 4 years ago

garyvdm commented 5 years ago

Steps to reproduce:

call: await client.connect(is_async=True) on a server that is not reachable

Actual:

Traceback (most recent call last):
  File "/home/garyvdm/dev/fnb/bpm-ng/ve/lib/python3.7/site-packages/bonsai/asyncio/aioconnection.py", line 60, in _poll
    return await asyncio.wait_for(fut, timeout)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 388, in wait_for
    return await fut
  File "/home/garyvdm/dev/fnb/bpm-ng/ve/lib/python3.7/site-packages/bonsai/asyncio/aioconnection.py", line 45, in _ready
    res = super().get_result(msg_id)
bonsai.errors.ConnectionError: Can't contact LDAP server. (0xFFFF [-1])

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/garyvdm/dev/fnb/bpm-ng/python/bpm/web_util.py", line 41, in rest_request_handler_inner
    result = await func(request)
  File "/home/garyvdm/dev/fnb/bpm-ng/python/bpm/web_app.py", line 92, in get_branches
    return await model.get_branches()
  File "/home/garyvdm/dev/fnb/bpm-ng/python/bpm/model/__init__.py", line 232, in get_branches
    async with self.connection_manager as connection:
  File "/home/garyvdm/dev/fnb/bpm-ng/python/bpm/model/__init__.py", line 75, in __aenter__
    self.connection = await self.client.connect(is_async=True)
  File "/home/garyvdm/dev/fnb/bpm-ng/ve/lib/python3.7/site-packages/bonsai/asyncio/aioconnection.py", line 62, in _poll
    self._loop.remove_reader(self.fileno())
  File "uvloop/loop.pyx", line 2302, in uvloop.loop.Loop.remove_reader
  File "uvloop/loop.pyx", line 724, in uvloop.loop.Loop._remove_reader
  File "uvloop/loop.pyx", line 682, in uvloop.loop.Loop._fileobj_to_fd
ValueError: Invalid file descriptor: -1

As you can see, a bonsai.errors.ConnectionError but another error was raised in a handler of that exception.

Expected:

A bonsai.errors.ConnectionError is raised.

noirello commented 5 years ago

Hi,

I'm trying to reproduce the error with the following snippet:

import asyncio
import bonsai

async def main():
    cli = bonsai.LDAPClient("ldap://unr.each.able")
    conn = await cli.connect(is_async=True)
    return conn

asyncio.run(main())

But it raises ConnectionError as it's expected. I tested with Python 3.6 on Ubuntu 18.04 and in python:3.7-alpine docker container, but the results were the same.

Can you send a code snippet and some more details about your environment? Maybe it's related to uvloop somehow.

garyvdm commented 5 years ago

I was able to reproduce it with this:

import asyncio
import bonsai

async def main():
    cli = bonsai.LDAPClient("ldap://10.0.0.1")
    conn = await cli.connect(is_async=True)
    return conn

asyncio.run(main())

10.0.0.1 is not reachable on my network. You may need to change this to something that is not reachable on your network.

noirello commented 5 years ago

Makes sense, I changed it and now getting the same result as you. I'll look into it.

noirello commented 5 years ago

I added a condition check to avoid removing invalid file descriptor.

noirello commented 4 years ago

New release is out, containing this fix.