SwiftKueryMySQL icon indicating copy to clipboard operation
SwiftKueryMySQL copied to clipboard

Original MySQL error message is lost when executing a query

Open janigro opened this issue 5 years ago • 4 comments

Problem

Hello... Unless I'm missing something, when executing a query, the returned error loses the original message generated by MySQL.

Example

These 3 statements return the same generic error description:

SELEC * FROM DUAL
LOCK TABLE some_table READ
SELECT * FROM non_existent_table

In all cases, QueryError.description returns the same message:

The operation couldn’t be completed. (SwiftKuery.QueryError error 2.)

However, their respective errors returned by MySQL are:

ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC * FROM DUAL' at line 1 
ERROR 1295: This command is not supported in the prepared statement protocol yet
ERROR 1146: Table 'myschema.non_existent_table' doesn't exist

Proposed Solution

A simple change in the MySQLConnection.execute(...) functions solves the problem. By replacing:

https://github.com/IBM-Swift/SwiftKueryMySQL/blob/27e631c8a5dfff19561423324f7881fb58246455/Sources/SwiftKueryMySQL/MySQLConnection.swift#L246

and also

https://github.com/IBM-Swift/SwiftKueryMySQL/blob/27e631c8a5dfff19561423324f7881fb58246455/Sources/SwiftKueryMySQL/MySQLConnection.swift#L272

with the following code:

if let error = error as? QueryError {
    return self.runCompletionHandler(.error(error), onCompletion: onCompletion)
} else {
    return self.runCompletionHandler(.error(QueryError.databaseError(error.localizedDescription)), onCompletion: onCompletion)
}

There may be other places where this needs to be done, but these are the most important.

Final Comments

Maybe this is intended behavior? However, during the development of a project, not having this information is really annoying.

At the moment, when we realize an error has occurred, we need to repeat the actions that took us to execute such query, use the debugger to pause execution, and get to the line of the library where the original error message is discarded. Not cool!

It would be nice to be able to log the real cause of the problem, so we can catch the problem the first time around the query fails.

Note that with the proposed change, the generic error The operation couldn’t be completed. (SwiftKuery.QueryError error 2.) is still accessible, using .localizedDescription instead of .description

If still, the current behavior is mandatory, couldn't we have a debug mode option? For example, some static variable in MySQLConnection that makes the library to return the original mysql messages, instead of the generic one: For example:

MySQLConnection.debug_mode = true

Thank you for your time!

janigro avatar May 05 '19 12:05 janigro

Any progress? feedback? I see the issue was assigned an unassigned more than 3 months ago, but no words on the status of this issue since then.

Thanks.

janigro avatar Aug 11 '19 06:08 janigro

@janigro This is something that we would like to address but unfortunately so far other issues have taken precedence. It looks like you have a good understanding of the problem, would you consider making the fix yourself and raising a pull request?

kilnerm avatar Aug 12 '19 06:08 kilnerm

Thanks. Ok, as soon as I get some time to work on this, I'll give it a try.

janigro avatar Aug 15 '19 09:08 janigro

Any thoughts on when this will be included? I've ran into this just now. I am using my package in a macOS app, and repeatedly had to step thru the code to see what was actually happening.

I have 2 databases, one from a legacy system, and one for the new system. Took me 20 minutes of debugging to find out what it was saying after placing a breakpoint in runCompletionHandler.

▿ QueryResult
  ▿ error : ERROR 1146: Table '{{database.tableName}}' doesn't exist
    - databaseError : "ERROR 1146: Table '{{database.tableName}}' doesn't exist"

Would appreciate if it told me the real reason instead of the generic message. It was looking at the right table, wrong database.

xeokeri avatar Dec 14 '19 07:12 xeokeri