From 8d4f1600eec43bf08686e8e65f2cd3b997778e11 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 29 Mar 2021 14:05:02 +0200 Subject: [PATCH] use vterror and not mysql.Error Signed-off-by: Andres Taylor --- go/mysql/sql_error.go | 74 ++++++++++++--------- go/vt/vterrors/state.go | 5 ++ go/vt/vttablet/tabletserver/tabletserver.go | 8 +-- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/go/mysql/sql_error.go b/go/mysql/sql_error.go index 491dd3e443..7f35c3c58d 100644 --- a/go/mysql/sql_error.go +++ b/go/mysql/sql_error.go @@ -98,40 +98,14 @@ func NewSQLErrorFromError(err error) error { msg := err.Error() match := errExtract.FindStringSubmatch(msg) - if len(match) < 2 { - // Map vitess error codes into the mysql equivalent - code := vterrors.Code(err) - num := ERUnknownError - ss := SSUnknownSQLState - switch code { - case vtrpcpb.Code_CANCELED, vtrpcpb.Code_DEADLINE_EXCEEDED, vtrpcpb.Code_ABORTED: - num = ERQueryInterrupted - ss = SSQueryInterrupted - case vtrpcpb.Code_UNKNOWN, vtrpcpb.Code_INVALID_ARGUMENT, vtrpcpb.Code_NOT_FOUND, vtrpcpb.Code_ALREADY_EXISTS, - vtrpcpb.Code_FAILED_PRECONDITION, vtrpcpb.Code_OUT_OF_RANGE, vtrpcpb.Code_UNAVAILABLE, vtrpcpb.Code_DATA_LOSS: - num = ERUnknownError - case vtrpcpb.Code_PERMISSION_DENIED, vtrpcpb.Code_UNAUTHENTICATED: - num = ERAccessDeniedError - ss = SSAccessDeniedError - case vtrpcpb.Code_RESOURCE_EXHAUSTED: - num = demuxResourceExhaustedErrors(err.Error()) - ss = SSClientError - case vtrpcpb.Code_UNIMPLEMENTED: - num = ERNotSupportedYet - ss = SSClientError - case vtrpcpb.Code_INTERNAL: - num = ERInternalError - ss = SSUnknownSQLState - } - - // Not found, build a generic SQLError. - return &SQLError{ - Num: num, - State: ss, - Message: msg, - } + if len(match) >= 2 { + return extractSQLErrorFromMessage(match, msg) } + return mapToSQLErrorFromErrorCode(err, msg) +} + +func extractSQLErrorFromMessage(match []string, msg string) error { num, err := strconv.Atoi(match[1]) if err != nil { return &SQLError{ @@ -149,6 +123,39 @@ func NewSQLErrorFromError(err error) error { return serr } +func mapToSQLErrorFromErrorCode(err error, msg string) error { + // Map vitess error codes into the mysql equivalent + num := ERUnknownError + ss := SSUnknownSQLState + switch vterrors.Code(err) { + case vtrpcpb.Code_CANCELED, vtrpcpb.Code_DEADLINE_EXCEEDED, vtrpcpb.Code_ABORTED: + num = ERQueryInterrupted + ss = SSQueryInterrupted + case vtrpcpb.Code_UNKNOWN, vtrpcpb.Code_INVALID_ARGUMENT, vtrpcpb.Code_NOT_FOUND, vtrpcpb.Code_ALREADY_EXISTS, + vtrpcpb.Code_FAILED_PRECONDITION, vtrpcpb.Code_OUT_OF_RANGE, vtrpcpb.Code_UNAVAILABLE, vtrpcpb.Code_DATA_LOSS: + num = ERUnknownError + case vtrpcpb.Code_PERMISSION_DENIED, vtrpcpb.Code_UNAUTHENTICATED: + num = ERAccessDeniedError + ss = SSAccessDeniedError + case vtrpcpb.Code_RESOURCE_EXHAUSTED: + num = demuxResourceExhaustedErrors(err.Error()) + ss = SSClientError + case vtrpcpb.Code_UNIMPLEMENTED: + num = ERNotSupportedYet + ss = SSClientError + case vtrpcpb.Code_INTERNAL: + num = ERInternalError + ss = SSUnknownSQLState + } + + // Not found, build a generic SQLError. + return &SQLError{ + Num: num, + State: ss, + Message: msg, + } +} + var stateToMysqlCode = map[vterrors.State]struct { num int state string @@ -182,6 +189,9 @@ var stateToMysqlCode = map[vterrors.State]struct { vterrors.WrongNumberOfColumnsInSelect: {num: ERWrongNumberOfColumnsInSelect, state: SSWrongNumberOfColumns}, vterrors.WrongTypeForVar: {num: ERWrongTypeForVar, state: SSClientError}, vterrors.WrongValueForVar: {num: ERWrongValueForVar, state: SSClientError}, + vterrors.ServerNotAvailable: {num: ERServerIsntAvailable, state: SSNetError}, + vterrors.CantDoThisInTransaction: {num: ERCantDoThisDuringAnTransaction, state: SSCantDoThisDuringAnTransaction}, + vterrors.NoSuchSession: {num: ERUnknownComError, state: SSNetError}, } func init() { diff --git a/go/vt/vterrors/state.go b/go/vt/vterrors/state.go index 4a9a33b122..8b4e8b9b4a 100644 --- a/go/vt/vterrors/state.go +++ b/go/vt/vterrors/state.go @@ -42,6 +42,7 @@ const ( NoDB InnodbReadOnly WrongNumberOfColumnsInSelect + CantDoThisInTransaction // not found BadDb @@ -50,6 +51,7 @@ const ( SPDoesNotExist UnknownSystemVariable UnknownTable + NoSuchSession // already exists DbCreateExists @@ -67,6 +69,9 @@ const ( // permission denied AccessDeniedError + // server not available + ServerNotAvailable + // No state should be added below NumOfStates NumOfStates ) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index dc0ebaaf1d..3bbb8b1d33 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -228,7 +228,7 @@ func NewTabletServer(name string, config *tabletenv.TabletConfig, topoServer *to // to complete the creation of TabletServer. func (tsv *TabletServer) InitDBConfig(target querypb.Target, dbcfgs *dbconfigs.DBConfigs, mysqld mysqlctl.MysqlDaemon) error { if tsv.sm.State() != StateNotConnected { - return mysql.NewSQLError(mysql.ERServerIsntAvailable, mysql.SSUnknownSQLState, "Server isn't available") + return vterrors.NewErrorf(vtrpcpb.Code_UNAVAILABLE, vterrors.ServerNotAvailable, "Server isn't available") } tsv.sm.Init(tsv, target) tsv.sm.target = target @@ -820,10 +820,10 @@ func (tsv *TabletServer) ExecuteBatch(ctx context.Context, target *querypb.Targe defer span.Finish() if len(queries) == 0 { - return nil, mysql.NewSQLError(mysql.EREmptyQuery, mysql.SSClientError, "Query was empty") + return nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.EmptyQuery, "Query was empty") } if asTransaction && transactionID != 0 { - return nil, mysql.NewSQLError(mysql.ERCantDoThisDuringAnTransaction, mysql.SSCantDoThisDuringAnTransaction, "You are not allowed to execute this command in a transaction") + return nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, mysql.ERCantDoThisDuringAnTransaction, "You are not allowed to execute this command in a transaction") } if tsv.enableHotRowProtection && asTransaction { @@ -1200,7 +1200,7 @@ func (tsv *TabletServer) ReserveExecute(ctx context.Context, target *querypb.Tar //Release implements the QueryService interface func (tsv *TabletServer) Release(ctx context.Context, target *querypb.Target, transactionID, reservedID int64) error { if reservedID == 0 && transactionID == 0 { - return mysql.NewSQLError(mysql.ERUnknownComError, mysql.SSNetError, "connection ID and transaction ID do not exist") + return vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.NoSuchSession, "connection ID and transaction ID do not exist") } return tsv.execRequest( ctx, tsv.QueryTimeout.Get(),