Skip to content

Add SQLState to MySQLError - #1321

Merged
methane merged 3 commits into
go-sql-driver:masterfrom
thopos:report-sqlstate-in-MySQLError
Apr 13, 2022
Merged

methane merged 3 commits into
go-sql-driver:masterfrom
thopos:report-sqlstate-in-MySQLError

Conversation

@thopos

@thopos thopos commented Apr 6, 2022

Copy link
Copy Markdown
Contributor

Description

Allow library users to distinguish user-defined from client / server errors.

Checklist

  • Code compiles correctly
  • Created tests which fail without the change (if possible)
  • All tests passing
  • Extended the README / documentation, if necessary
  • Added myself / the copyright holder to the AUTHORS file

@shogo82148 shogo82148 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it needs some little memory allocations, but not so frequently.
#1322 is acceptable for me.

@jmhodges @arnehormann @methane How do you think about it?

Comment thread packets.go Resolved
@thopos
thopos force-pushed the report-sqlstate-in-MySQLError branch from 4ab8a7a to 14893f1 Compare April 6, 2022 13:06
Comment thread packets.go Resolved
Comment thread errors.go Resolved
@thopos
thopos force-pushed the report-sqlstate-in-MySQLError branch from 14893f1 to c0031c2 Compare April 11, 2022 10:31
shogo82148
shogo82148 previously approved these changes Apr 12, 2022

@shogo82148 shogo82148 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼

Comment thread errors.go Resolved

@methane methane left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove IsWithSQLState.

to allow library users to distinguish user-defined from client / server errors
@thopos
thopos force-pushed the report-sqlstate-in-MySQLError branch from c0031c2 to 0e8599a Compare April 12, 2022 09:32
@methane methane changed the title Report sqlstate in my sql error Add SQLState to MySQLError Apr 13, 2022
Comment thread errors.go Resolved
@methane
methane merged commit ad9fa14 into go-sql-driver:master Apr 13, 2022
@thopos

thopos commented Apr 13, 2022

Copy link
Copy Markdown
Contributor Author

Thank you @shogo82148 and @methane for your patience and thorough review.

@iseki0

iseki0 commented Sep 29, 2024 •

Copy link
Copy Markdown

Why you add it as a field instead of a method?
So sadly, all user of the driver has to hard-dependent it.

FYI:
https://github.com/jackc/pgx/blob/a95cfbb433143477082823c8e93d75b0eafc71da/pgconn/errors.go#L57-L60

@arnehormann

Copy link
Copy Markdown
Member

@iseki0 thank you for that input. but even if you are right - first, we cannot change it now. second, that would have been a wonderful code review comment. why did you sadly have to add it more than a year after it was merged and not when it was still open?

Honestly, this is passive aggressive and not constructive and it contributes to maintainer burnout. why?

something like: "To bad it's too late now, but for similar future consideration: making it a method instead of a function would have helped for situation xyz." which still gets the point across and helps. but without one-upping.

@iseki0

iseki0 commented Sep 29, 2024

Copy link
Copy Markdown

@iseki0 thank you for that input. but even if you are right - first, we cannot change it now. second, that would have been a wonderful code review comment. why did you sadly have to add it more than a year after it was merged and not when it was still open?

Honestly, this is passive aggressive and not constructive and it contributes to maintainer burnout. why?

something like: "To bad it's too late now, but for similar future consideration: making it a method instead of a function would have helped for situation xyz." which still gets the point across and helps. but without one-upping.

@arnehormann
Sorry for my irrational and negative comments.
I just curious why it's a field. And, I think we have a chance to improve the compatibility:
Can we use the Unwrap() error method to returns an error object that implement the SQLState() string method?
I see it smells... a bit ugly. But it will works with other famous SQL drivers, such as the PostgreSQL.

My native language is not English. Sorry for my poor English.

@iseki0

iseki0 commented Sep 29, 2024

Copy link
Copy Markdown

Can we use the Unwrap() error method to returns an error object that implement the SQLState() string method?

In Go, we often use fmt.Errorf("prefix: %w", e) to wrap an error, because in Go we haven't a stacktrace.
So I think if people want to read the SQL state from an error object, they will use errors.As() like:

var errorWithSQLState interface{ SQLState() string }
if errors.As(e, &errorWithSQLState) {
  fmt.Println(errorWithSQLState.SQLState())
}

If we use the Unwrap() error method, we will have a chance to keep compatibility with the PostgreSQL driver.
At least... Many SQL state code is standarized, so many program can use it to handling DB error.

@methane

methane commented Sep 30, 2024 •

Copy link
Copy Markdown
Member

I just curious why it's a field.

Because I never think about such use cases. Your comment is the first time I heard about using SQLState as DB-independent error code.

Both of database/sql and DB API in Python defines SQLState. sqlite3 error code doesn't mention about SQLState. They are my only experience.

Is there any famous ORM implementation (not limited to Go) using SQLState as DB-independent error code?

But it will works with other famous SQL drivers, such as the PostgreSQL?

Could you list several other SQL drivers?

Currently, I feel abusing Unrap() for this is not worth enough.

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

Could you list several other SQL drivers?

https://pkg.go.dev/github.com/godror/godror#OraErr.SQLState
https://github.com/asifjalil/cli/blob/2598d7f01fdb79080f4a7837561a9fbe019eda39/error.go#L87-L89

Both of database/sql and DB API in Python defines SQLState.

😦Could you show me where the definition in the database/sql? I haven't found. I think if go standarized it, we should obey the standards. Just like the JDBC

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

Is there any famous ORM implementation (not limited to Go) using SQLState as DB-independent error code?

You can see the function in hibernate:
https://github.com/hibernate/hibernate-orm/blob/eb03db74012665a738bbaea737bbbdc91ac15ad8/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java#L80-L124
It convert some well-known SQL state to program exceptions...

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

Fortunately, we have Unwrap() []error now. We have a chance, even if we already use error wrapping.

@methane

methane commented Sep 30, 2024

Copy link
Copy Markdown
Member

😦Could you show me where the definition in the database/sql?

https://pkg.go.dev/database/sql

@methane

methane commented Sep 30, 2024

Copy link
Copy Markdown
Member

Is there any Go ORM that want to use SQLState for DB-independent error handler?

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

😦Could you show me where the definition in the database/sql?

https://pkg.go.dev/database/sql

image
Show me the paragraph, thank you

@methane

methane commented Sep 30, 2024 •

Copy link
Copy Markdown
Member

No paragraph at all. I meant database/sql doesn't provide a way to DB-independent API for SQLState. And this driver is based on it.

And there is no feature request to support SQLState on database/sql nor PyMySQL nor mysqlclient-python. I doubt that using SQLState is common practice.

@arnehormann

Copy link
Copy Markdown
Member

@iseki0 thank you for that input. but even if you are right - first, we cannot change it now. second, that would have been a wonderful code review comment. why did you sadly have to add it more than a year after it was merged and not when it was still open?
Honestly, this is passive aggressive and not constructive and it contributes to maintainer burnout. why?
something like: "To bad it's too late now, but for similar future consideration: making it a method instead of a function would have helped for situation xyz." which still gets the point across and helps. but without one-upping.

@arnehormann Sorry for my irrational and negative comments. I just curious why it's a field. And, I think we have a chance to improve the compatibility: Can we use the Unwrap() error method to returns an error object that implement the SQLState() string method? I see it smells... a bit ugly. But it will works with other famous SQL drivers, such as the PostgreSQL.

My native language is not English. Sorry for my poor English.

thank you for this, it's the basis for a more constructive discussion.

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

I meant database/sql doesn't provide a way to DB-independent API for SQLState.

That's the problem. 😥😫

@arnehormann

arnehormann commented Sep 30, 2024 •

Copy link
Copy Markdown
Member

@iseki0 this driver aligns to database/sql. There might be capabilities not included there (e.g. providing io.Reader for LOAD DATA INFILE LOCAL), but we decide on an api without any global standard.
If it were a method, it could have been named differently or provided a different return code ([]byte vs [6]byte vs string ...). Without an interface in database/sql, it might still be wrong.
Constructively, you can still get it without adding the driver as a dependency if you use reflect to retrieve the field. Then you just have to know what it looks like - which is not a huge problem as it won't change.
Might this help you?
And as an alternative, you can of course also propose it as an addition to database/sql. which we would adopt as soon as we can.

@iseki0

iseki0 commented Sep 30, 2024

Copy link
Copy Markdown

@iseki0 this driver aligns to database/sql. There might be capabilities not included there (e.g. providing io.Reader for LOAD DATA INFILE LOCAL), but we decide on an api without any global standard.
If it were a method, it could have been named differently or provided a different return code ([]byte vs [6]byte vs string ...). Without an interface in database/sql, it might still be wrong.
Constructively, you can still get it without adding the driver as a dependency if you use reflect to retrieve the field. Then you just have to know what it looks like - which is not a huge problem as it won't change.
Might this help you?
And as an alternative, you can of course also propose it as an addition to database/sql. which we would adopt as soon as we can.

Your reply is helpful. I'm also afraid that the Go team might give a standard which conflict with the current behaviour. The problem is Go's.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants