Error Packet https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_err_packet.html
(data []byte)
| 586 | // Error Packet |
| 587 | // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_err_packet.html |
| 588 | func (mc *mysqlConn) handleErrorPacket(data []byte) error { |
| 589 | if data[0] != iERR { |
| 590 | return ErrMalformPkt |
| 591 | } |
| 592 | |
| 593 | // 0xff [1 byte] |
| 594 | |
| 595 | // Error Number [16 bit uint] |
| 596 | errno := binary.LittleEndian.Uint16(data[1:3]) |
| 597 | |
| 598 | // 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION |
| 599 | // 1290: ER_OPTION_PREVENTS_STATEMENT (returned by Aurora during failover) |
| 600 | // 1836: ER_READ_ONLY_MODE |
| 601 | if (errno == 1792 || errno == 1290 || errno == 1836) && mc.cfg.RejectReadOnly { |
| 602 | // Oops; we are connected to a read-only connection, and won't be able |
| 603 | // to issue any write statements. Since RejectReadOnly is configured, |
| 604 | // we throw away this connection hoping this one would have write |
| 605 | // permission. This is specifically for a possible race condition |
| 606 | // during failover (e.g. on AWS Aurora). See README.md for more. |
| 607 | // |
| 608 | // We explicitly close the connection before returning |
| 609 | // driver.ErrBadConn to ensure that `database/sql` purges this |
| 610 | // connection and initiates a new one for next statement next time. |
| 611 | mc.Close() |
| 612 | return driver.ErrBadConn |
| 613 | } |
| 614 | |
| 615 | me := &MySQLError{Number: errno} |
| 616 | |
| 617 | pos := 3 |
| 618 | |
| 619 | // SQL State [optional: # + 5bytes string] |
| 620 | if data[3] == 0x23 { |
| 621 | copy(me.SQLState[:], data[4:4+5]) |
| 622 | pos = 9 |
| 623 | } |
| 624 | |
| 625 | // Error Message [string] |
| 626 | me.Message = string(data[pos:]) |
| 627 | |
| 628 | return me |
| 629 | } |
| 630 | |
| 631 | func readStatus(b []byte) statusFlag { |
| 632 | return statusFlag(b[0]) | statusFlag(b[1])<<8 |
no test coverage detected