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 error shown - (2003, "Can't connect to MySQL server on 'localhost'") #792

Closed
1 task done
leothewolf opened this issue May 30, 2022 · 6 comments · Fixed by #839
Closed
1 task done

Improper error shown - (2003, "Can't connect to MySQL server on 'localhost'") #792

leothewolf opened this issue May 30, 2022 · 6 comments · Fixed by #839
Labels
bug pymysql-port Awaiting or implementing port of PyMySQL change
Milestone

Comments

@leothewolf
Copy link

leothewolf commented May 30, 2022

Describe the bug

Well I formatted my pc and had to reinstall all the stuff and while I started working with my code I started receiving error (2003, "Can't connect to MySQL server on 'localhost'") I was not expecting that as my code worked flawless and at that time my discord bot which uses the same code was up and running well. So after two hours of going through all code I found that I had added db parameter in aiomysql.create_pool and I had forgot to create a database with the db mentioned there so that was the problem! So what I want is it should throw error that db is not found rather than (2003, "Can't connect to MySQL server on 'localhost'")

To Reproduce

I am running latest version of python 3.10 and pip installed aiomysql

Just dont make a database and try creating aiomysql.create_pool object with mentioning db you will get the error!

I used following code:

import asyncio
import aiomysql

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)


async def test_example():
    try:
        conn = await aiomysql.create_pool(host='localhost', port=3306, user='user', password='pass',loop=loop,db="uncreated_db")
    except Exception as e:
        print(e)

loop.run_until_complete(test_example())

Expected behavior

Will throw this error : (2003, "Can't connect to MySQL server on 'localhost'")

Logs/tracebacks

Will throw this error : ``(2003, "Can't connect to MySQL server on 'localhost'")``

Python Version

$ Python 3.10.4

aiomysql Version

$ python -m pip show aiomysql

PyMySQL Version

1.0.2

SQLAlchemy Version

1.0.2

OS

Windows

Database type and version

MySQL : 8.0.29

Additional context

No response

Code of Conduct

  • I agree to follow the aio-libs Code of Conduct
@leothewolf leothewolf added the bug label May 30, 2022
@leothewolf leothewolf changed the title Improper error shown Improper error shown - (2003, "Can't connect to MySQL server on 'localhost'") May 30, 2022
@Nothing4You
Copy link
Collaborator

Hm, the error for unknown database is raised, but due to this happening while attempting to connect it's reraised as connection error:

Traceback (most recent call last):
  File ".../aiomysql/aiomysql/connection.py", line 540, in _connect
    await self._request_authentication()
  File ".../aiomysql/aiomysql/connection.py", line 833, in _request_authentication
    auth_packet = await self._read_packet()
  File ".../aiomysql/aiomysql/connection.py", line 641, in _read_packet
    packet.raise_for_error()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1049, "Unknown database 'uncreated_db'")

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

Traceback (most recent call last):
  File ".../aiomysql/issue-792.py", line 13, in <module>
    asyncio.run(test_example())
  File ".../.asdf/installs/python/3.10.2/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File ".../.asdf/installs/python/3.10.2/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
    return future.result()
  File ".../aiomysql/issue-792.py", line 7, in test_example
    conn = await aiomysql.create_pool(host='localhost', port=3306, user='root', password='', db="uncreated_db")
  File ".../aiomysql/aiomysql/pool.py", line 29, in _create_pool
    await pool._fill_free_pool(False)
  File ".../aiomysql/aiomysql/pool.py", line 182, in _fill_free_pool
    conn = await connect(echo=self._echo, loop=self._loop,
  File ".../aiomysql/aiomysql/connection.py", line 75, in _connect
    await conn._connect()
  File ".../aiomysql/aiomysql/connection.py", line 558, in _connect
    raise OperationalError(2003,
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost'")

The same applies when just connecting without a pool.

in comparison, PyMySQL raises the database error:

Traceback (most recent call last):
  File ".../aiomysql/issue-792-pm.py", line 4, in <module>
    connection = pymysql.connect(
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 353, in __init__
    self.connect()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 633, in connect
    self._request_authentication()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 907, in _request_authentication
    auth_packet = self._read_packet()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 725, in _read_packet
    packet.raise_for_error()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1049, "Unknown database 'uncreated_db'")

@Nothing4You Nothing4You added the pymysql-port Awaiting or implementing port of PyMySQL change label Jul 10, 2022
@Nothing4You
Copy link
Collaborator

PyMySQL has a little more logic there to only create OperationalError for OSError and IOError: https://github.com/PyMySQL/PyMySQL/blob/v1.0.2/pymysql/connections.py#L655-L664

Looks like PyMySQL has been doing this since about 2015: PyMySQL/PyMySQL@125daaa

@Nothing4You Nothing4You added this to the 0.2 milestone Jul 11, 2022
@leothewolf
Copy link
Author

Hm, the error for unknown database is raised, but due to this happening while attempting to connect it's reraised as connection error:

Traceback (most recent call last):
  File ".../aiomysql/aiomysql/connection.py", line 540, in _connect
    await self._request_authentication()
  File ".../aiomysql/aiomysql/connection.py", line 833, in _request_authentication
    auth_packet = await self._read_packet()
  File ".../aiomysql/aiomysql/connection.py", line 641, in _read_packet
    packet.raise_for_error()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1049, "Unknown database 'uncreated_db'")

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

Traceback (most recent call last):
  File ".../aiomysql/issue-792.py", line 13, in <module>
    asyncio.run(test_example())
  File ".../.asdf/installs/python/3.10.2/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File ".../.asdf/installs/python/3.10.2/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
    return future.result()
  File ".../aiomysql/issue-792.py", line 7, in test_example
    conn = await aiomysql.create_pool(host='localhost', port=3306, user='root', password='', db="uncreated_db")
  File ".../aiomysql/aiomysql/pool.py", line 29, in _create_pool
    await pool._fill_free_pool(False)
  File ".../aiomysql/aiomysql/pool.py", line 182, in _fill_free_pool
    conn = await connect(echo=self._echo, loop=self._loop,
  File ".../aiomysql/aiomysql/connection.py", line 75, in _connect
    await conn._connect()
  File ".../aiomysql/aiomysql/connection.py", line 558, in _connect
    raise OperationalError(2003,
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost'")

The same applies when just connecting without a pool.

in comparison, PyMySQL raises the database error:

Traceback (most recent call last):
  File ".../aiomysql/issue-792-pm.py", line 4, in <module>
    connection = pymysql.connect(
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 353, in __init__
    self.connect()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 633, in connect
    self._request_authentication()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 907, in _request_authentication
    auth_packet = self._read_packet()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/connections.py", line 725, in _read_packet
    packet.raise_for_error()
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File ".../aiomysql/venv/lib/python3.10/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1049, "Unknown database 'uncreated_db'")

Ohh ok ok I didnt notice the database error but it would be great if it somehows appears later on like we atleast know

@leothewolf
Copy link
Author

PyMySQL has a little more logic there to only create OperationalError for OSError and IOError: https://github.com/PyMySQL/PyMySQL/blob/v1.0.2/pymysql/connections.py#L655-L664

Looks like PyMySQL has been doing this since about 2015: PyMySQL/PyMySQL@125daaa

Well it would be great if we can somehow make the database not found error later on so that the user knows that its because of database as there might be people like me who wont notice the error within error

@AndreMPCosta
Copy link

AndreMPCosta commented Aug 16, 2022

Why do we have this bit of code:

  except Exception as e:
      if self._writer:
          self._writer.transport.close()
      self._reader = None
      self._writer = None
      raise OperationalError(2003,
                             "Can't connect to MySQL server on %r" %
                             self._host) from e

Instead of raising the original exception? We lose all the info and the error code (auth failed for 1045 for example, 1049 database not found, etc).

This approach does not make much sense, putting everything as an Operational Error 2003 code.

except Exception as e:

Nothing4You added a commit to Nothing4You/aiomysql that referenced this issue Aug 23, 2022
aiomysql now reraises the original exception during connect() if it's not `IOError` or `OSError`.
This was previously always raised as `OperationalError`.

fixes aio-libs#792
Nothing4You added a commit to Nothing4You/aiomysql that referenced this issue Aug 23, 2022
aiomysql now reraises the original exception during connect() if it's not `IOError`, `OSError` or `asyncio.TimeoutError`.
This was previously always raised as `OperationalError`.

fixes aio-libs#792
@Nothing4You
Copy link
Collaborator

#839 should resolve this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug pymysql-port Awaiting or implementing port of PyMySQL change
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants