pBlueG / SA-MP-MySQL

MySQL plugin for San Andreas Multiplayer
BSD 3-Clause "New" or "Revised" License
196 stars 80 forks source link

OnQueryError isn't being called for non-threaded queries #204

Open dotSILENT opened 5 years ago

dotSILENT commented 5 years ago

OnQueryError isn't being called for errors thrown from mysql_query() (unthreaded) Errors are being logged to the mysql.log file, but the callback isn't getting called. Haven't checked it on Linux yet, but I'm assuming it may be the same. Detecting query-specific errors is kinda useful, for example when you don't want to corrupt/loose the data of the players. I normally crashed the server in case of any error in StrickenKid's plugin, would like to do the same here. And while threaded queries are often better, there are many places where they aren't really needed (for example loading data under OnGameModeInit), or using them is just too much of a trouble (creating another callback).

I've set up a clean server with a very simple script:

#include <a_samp>
#include <a_mysql>

main() {}

public OnGameModeInit()
{
        mysql_log(ALL);
    new MySQL:hMysql = mysql_connect("localhost", "root", "pw", "db");

    mysql_query(hMysql, "SELECT * FROM nonexistenttable;");
    mysql_query(hMysql, "SELECT AAAAAAAA(*) FORM nonexistenttable;");
}

public OnQueryError(errorid, const error[], const callback[], const query[], MySQL:handle)
{
    printf("OnMysqlError(%d, %s, %s, %s)", errorid, error, callback, query);
    return 1;
}

And I actually misspelled the credentials, and the callback wasn't called at all. Not even once, despite outputting all the errors in mysql.log:

[03:00:58] [ERROR] CConnection::CConnection - establishing connection to MySQL database failed: #2002 'Can't connect to MySQL server on 'localhost' (10061)'
[03:00:58] [DEBUG] CThreadedConnection::CThreadedConnection(this=0x3acd020, connection=0x3acd020)
[03:00:58] [DEBUG] CConnection::CConnection(this=0x3c95020, host='localhost', user='root', passw='**', db='ddb', options=0x89fbf0)
[03:00:58] [DEBUG] CThreadedConnection::WorkerFunc(this=0x3acd020, connection=0x3acd020)
[03:01:00] [ERROR] CConnection::CConnection - establishing connection to MySQL database failed: #2002 'Can't connect to MySQL server on 'localhost' (10061)'
[03:01:00] [DEBUG] CThreadedConnection::CThreadedConnection(this=0x3c95020, connection=0x3c95020)
[03:01:00] [INFO] Connection handle with id '1' successfully created.
[03:01:00] [DEBUG] CHandleManager::Create - new handle = 0x8b12e8
[03:01:00] [DEBUG] mysql_connect: return value: '1'
[03:01:00] [DEBUG] mysql_query(1, "SELECT * FROM nonexistenttable;", 1)
[03:01:00] [DEBUG] CHandle::Execute(this=0x8b12e8, type=3, query=0x8b4898)
[03:01:00] [DEBUG] CConnection::Execute(query=0x8b4898, this=0x8aa508, connection=0x8b4998)
[03:01:00] [DEBUG] CHandle::Execute - return value: false
[03:01:00] [DEBUG] mysql_query: return value: '0'
[03:01:00] [DEBUG] mysql_query(1, "SELECT AAAAAAAA(*) FORM nonexistenttable;", 1)
[03:01:00] [DEBUG] CHandle::Execute(this=0x8b12e8, type=3, query=0x8b4898)
[03:01:00] [DEBUG] CConnection::Execute(query=0x8b4898, this=0x8aa508, connection=0x8b4998)
[03:01:00] [DEBUG] CHandle::Execute - return value: false
[03:01:00] [DEBUG] mysql_query: return value: '0'
[03:01:00] [DEBUG] CThreadedConnection::WorkerFunc(this=0x3c95020, connection=0x3c95020)

After succesfully connecting, it still hasn't triggered even once, despite obvious errors: [03:07:26] [ERROR] error #1064 while executing query "SELECT AAAAAAAA(*) FORM nonexistenttable;": You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '*) FORM nonexistenttable' at line 1

After changing any of the queries above to use mysql_tquery(), the callback was called succesfully (but only for _tquery)

maddinat0r commented 5 years ago

Yeah, OnQueryError gets only called for mysql_tquery and mysql_pquery. I'll look into this. I'm currently not sure if I'll add a call to OnQueryError, because you can use mysql_errno and mysql_error to check for errors after an unthreaded query. However, having a central callback for all query errors (including ORM-generated queries, as they currently also do not call any error callback) would make it easier to use for everyone.