Closed MHShetty closed 2 years ago
Good day. There is separate logging branch. You can see readme Troubleshooting how to deal with logging. This timeout bug happens a lot.but I can no reproduce it locally. If you can provide logging information after switching to logging branch I will be very happy
Also you can try to disable TLS connection, by passing secure: false, and see does it helps
Hi @zim32,
Actually the logs I have posted in the last answer are mainly related to the RangeError
that gets thrown as the (MySQLPacketInitialHandshake.decode
) factory method incorrectly parses the error packet as a valid packet containing the information it is otherwise trying to retrieve.
The actual format of the packet seems to be the one mentioned here: https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html
Please try comparing the above format to the (additional) logs shared earlier (The offset of protocolVersion yields 255).
flutter: Isconnected: false
flutter: TypedDataView(cid: 152)
flutter: protocolVersion: 255
flutter: Server version: jοΏ½Host 'REPLACED_WITH_XYZ' is not allowed to connect to this MySQL server
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:48:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:261:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:154:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:113:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:110:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#12 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#13 _StreamController._add (dart:async/stream_controller.dart:648:7)
#14 _StreamController.add (dart:async/stream_controller.dart:596:5)
#15 _Socket._onData (dart:io-patch/socket_patch.dart:2314:41)
#16 _rootRunUnary (dart:async/zone.dart:1442:13)
#17 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#22 _StreamController._add (dart:async/stream_controller.dart:648:7)
#23 _StreamController.add (dart:async/stream_controller.dart:596:5)
#24 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1839:33)
#25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1322:14)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
flutter: Isconnected: false
You'll might want to add some code to handle that correctly, so this issue is mainly for that. You'll can mark this as fixed once this issue gets resolved. Please do let me know if I could help you'll with a quick PR for the same.
You can see readme Troubleshooting how to deal with logging.
At the moment, I'm facing issues with connecting to MySQL database with the same timeout error you just mentioned, but we could probably discuss that on a separate issue once I'm back with the logs.
Also you can try to disable TLS connection, by passing secure: false, and see does it helps
I had tried disabling secure connection too, as stated by you another issue, doesn't seem to unfortunately help.
Thanks for the quick response @zim32!
At least in logging branch I can see raw bytes, coming from your mysql server. I can then compare it with what I have locally and spot the difference
Without this information it is very hard to find out the problem
Oh sure, I'll just share them soon for this issue too in that case π
Here are the logs from the logging
branch: (@zim32)
Launching lib\main.dart on Windows in debug mode...
Building Windows application...
Debug service listening on ws://127.0.0.1:55172/MiqCaU64CtY=/ws
Syncing files to device Windows...
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:83:12)
flutter: β #1 init (package:test_project/sql.dart:11:39)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Establishing socket connection
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:83:12)
flutter: β #1 init (package:test_project/sql.dart:11:39)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Establishing socket connection
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: Isconnected: false
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:85:12)
flutter: β #1 <asynchronous suspension>
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Socket connection established
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:85:12)
flutter: β #1 <asynchronous suspension>
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Socket connection established
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:163:12)
flutter: β #1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing socket data. Current state is _MySQLConnectionState.waitInitialHandshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:279:12)
flutter: β #1 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing initial handshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:42:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:281:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:120:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#12 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#13 _StreamController._add (dart:async/stream_controller.dart:648:7)
#14 _StreamController.add (dart:async/stream_controller.dart:596:5)
#15 _Socket._onData (dart:io-patch/socket_patch.dart:2314:41)
#16 _rootRunUnary (dart:async/zone.dart:1442:13)
#17 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#22 _StreamController._add (dart:async/stream_controller.dart:648:7)
#23 _StreamController.add (dart:async/stream_controller.dart:596:5)
#24 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1839:33)
#25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1322:14)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
Also, please note that the timeout related issue (Issue #26) is entirely different from this issue that is related to error handling in case of an unexpected host name. The issue over here is that the factory method MySQLPacketInitialHandshake.decode
tries to incorrectly pass the error packet as a valid packet (based on its format).
The error packet is much shorter and hence the RangeError
that gets thrown.
The documented for the error packet (as mentioned in the earlier comments) is here: https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html
Could you also provide code, where you are establishing connection? You can mask user password if you want
Hm.. I gues the problem is here https://github.com/zim32/mysql.dart/blob/main/lib/src/mysql_protocol/packet/packet_initial_handshake.dart#L39
I guess length of decoded string is not equal to bytes in your case. Seems like you server version string contains some unusual characters. I need to rewrite this piece of code
I have fixed decoding strings. Latest changes are in main branch. Can you point dart pub to main branch and test it? It should work.
Hi @zim32,
Really sorry for the late reply, actually I got really busy with some other work and email notifications didn't notify me of the message that you had shared around 2 days ago.
I tried testing the code (after changing the ref
to main under your package name and git pubspec.yaml
and running pub get
successfully) and it still shows the same error unfortunately:
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:42:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:261:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:154:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:113:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:110:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
Not really sure about the encoding change, but the from what I am able to understand, the issue seems to be with parsing an error packet as a valid packet. We might need to write some code to handle that (based on the design of the library).
Please try tracing the data packets received while supplying the actual IP of your machine instead of localhost (or maybe a IP that's not a part of the network) while trying to connect to a local MySQL instance, and then logging. The packet that gets delivered then seems to be of the format of an error packet mentioned here in the docs - https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html
Thanks a lot for sharing your valuable time!
First packet is always initial handshake. It can not be error packet
I can not understand why there are two Establishing connection in your logs.
First packet is always initial handshake. It can not be error packet
It doesn't seem to be the first packet here.. Tried logging again.
I can not understand why there are two Establishing connection in your logs.
Really sorry for that.. actually I had written some debug code that might have caused double initialization back then.
Here are the latest logs:
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:83:12)
flutter: β #1 init (package:test_project/sql.dart:11:39)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Establishing socket connection
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: Isconnected: false
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:85:12)
flutter: β #1 <asynchronous suspension>
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Socket connection established
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:163:12)
flutter: β #1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing socket data. Current state is _MySQLConnectionState.waitInitialHandshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:280:12)
flutter: β #1 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing initial handshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:42:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:282:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:120:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#12 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#13 _StreamController._add (dart:async/stream_controller.dart:648:7)
#14 _StreamController.add (dart:async/stream_controller.dart:596:5)
#15 _Socket._onData (dart:io-patch/socket_patch.dart:2314:41)
#16 _rootRunUnary (dart:async/zone.dart:1442:13)
#17 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#22 _StreamController._add (dart:async/stream_controller.dart:648:7)
#23 _StreamController.add (dart:async/stream_controller.dart:596:5)
#24 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1839:33)
#25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1322:14)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
It still seems to because of incorrectly parsing a valid packet as an error packet.
Ok let's go deeper. On logging branch, open lib/src/mysql_client/connection.dart file and change
Find line at the top: final loggingLevel = Level.debug;
And change it to: final loggingLevel = Level.verbose;
Then test again and copy-paste logs please.
Sure @zim32, just changed the the logging to verbose by re-built the app.
Here are the latest logs now:
Launching lib\main.dart on Windows in debug mode...
Building Windows application...
Debug service listening on ws://127.0.0.1:52784/zdk3EvYGJWY=/ws
Syncing files to device Windows...
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:83:12)
flutter: β #1 init (package:test_project/sql.dart:11:39)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Establishing socket connection
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: Isconnected: false
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:85:12)
flutter: β #1 <asynchronous suspension>
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Socket connection established
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:163:12)
flutter: β #1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing socket data. Current state is _MySQLConnectionState.waitInitialHandshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:280:12)
flutter: β #1 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing initial handshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:42:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:282:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:120:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#12 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#13 _StreamController._add (dart:async/stream_controller.dart:648:7)
#14 _StreamController.add (dart:async/stream_controller.dart:596:5)
#15 _Socket._onData (dart:io-patch/socket_patch.dart:2314:41)
#16 _rootRunUnary (dart:async/zone.dart:1442:13)
#17 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#22 _StreamController._add (dart:async/stream_controller.dart:648:7)
#23 _StreamController.add (dart:async/stream_controller.dart:596:5)
#24 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1839:33)
#25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1322:14)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
Not really sure, I don't think there are any separate or additional log statements at this stage unfortunately (specifically for verbose).
No changes. Very strange. There should be more info
I thinks flutter is making some magic and ignores you change
Is it possible that flutter reverts all local changes before building?
Ok I will try to setup flutter and test
Hey @zim32,
Sorry for the unexpected delay.
I tried re-building the app too. Not really certain about how things are working behind the hood.
Here are some additional logs for the same that might help:
Launching lib\main.dart on Windows in debug mode...
Building Windows application...
Debug service listening on ws://127.0.0.1:55706/d4Soajcr17M=/ws
Syncing files to device Windows...
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:83:12)
flutter: β #1 init (package:test_project/sql.dart:11:39)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Establishing socket connection
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection.createConnection (package:mysql_client/src/mysql_client/connection.dart:85:12)
flutter: β #1 <asynchronous suspension>
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Socket connection established
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:163:12)
flutter: β #1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing socket data. Current state is _MySQLConnectionState.waitInitialHandshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β #0 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:280:12)
flutter: β #1 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: β π Processing initial handshake
flutter: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flutter: Buffer: [255, 106, 4, 72, 111, 115, 116, 32, 39, 73, 78, 84, 77, 85, 77, 49, 76, 65, 80, 48, 53, 56, 56, 39, 32, 105, 115, 32, 110, 111, 116, 32, 97, 108, 108, 111, 119, 101, 100, 32, 116, 111, 32, 99, 111, 110, 110, 101, 99, 116, 32, 116, 111, 32, 116, 104, 105, 115, 32, 77, 121, 83, 81, 76, 32, 115, 101, 114, 118, 101, 114]
flutter: byteData: TypedDataView(cid: 152)
flutter: protocolVersion: 255
flutter: serverVersion: jHost 'SOME_RANDOM_NAME' is not allowed to connect to this MySQL server
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: RangeError (byteOffset): Invalid value: Not in inclusive range 0..67: 72
#0 _ByteDataView.getUint32 (dart:typed_data-patch/typed_data_patch.dart:4864:7)
#1 new MySQLPacketInitialHandshake.decode (package:mysql_client/src/mysql_protocol/packet/packet_initial_handshake.dart:49:35)
#2 new MySQLPacket.decodeInitialHandshake (package:mysql_client/src/mysql_protocol/mysql_packet.dart:112:49)
#3 MySQLConnection._processInitialHandshake (package:mysql_client/src/mysql_client/connection.dart:282:32)
#4 MySQLConnection._processSocketData (package:mysql_client/src/mysql_client/connection.dart:167:13)
#5 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:123:17)
#6 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:120:42)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#10 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#12 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#13 _StreamController._add (dart:async/stream_controller.dart:648:7)
#14 _StreamController.add (dart:async/stream_controller.dart:596:5)
#15 _Socket._onData (dart:io-patch/socket_patch.dart:2314:41)
#16 _rootRunUnary (dart:async/zone.dart:1442:13)
#17 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#19 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#20 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#21 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:774:19)
#22 _StreamController._add (dart:async/stream_controller.dart:648:7)
#23 _StreamController.add (dart:async/stream_controller.dart:596:5)
#24 new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1839:33)
#25 _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1322:14)
#26 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#27 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
I modified the factory method MySQLPacketInitialHandshake.decode
to log the buffer
, byteData
, protocolVersion
, etc. values. (since the error pointed there)
(connectionID
wasn't included as the code crashes while trying to obtain it mainly because of the bad/unexpected format of the packet)
Here's the modified code of the factory method (for reference):
factory MySQLPacketInitialHandshake.decode(Uint8List buffer) {
final byteData = ByteData.sublistView(buffer);
int offset = 0;
print("Buffer: $buffer");
print("byteData: $byteData");
// protocol version
final protocolVersion = byteData.getUint8(offset);
offset += 1;
print("protocolVersion: $protocolVersion");
// server version
final serverVersion = buffer.getAsciNullTerminatedString(offset);
offset += serverVersion.length + 1;
print("serverVersion: $serverVersion");
// connection id
final connectionID = byteData.getUint32(offset, Endian.little);
offset += 4;
// auth-plugin-data-part-1
final authPluginDataPart1 =
Uint8List.sublistView(buffer, offset, offset + 8);
offset += 9; // 8 + filler;
// capability flags (lower 2 bytes)
final capabilitiesBytesData = ByteData(4);
capabilitiesBytesData.setUint8(3, buffer[offset]);
capabilitiesBytesData.setUint8(2, buffer[offset + 1]);
offset += 2;
// character set
final charset = byteData.getUint8(offset);
offset += 1;
final statusFlags = Uint8List.sublistView(buffer, offset, offset + 2);
offset += 2;
// capability flags (upper 2 bytes)
capabilitiesBytesData.setUint8(1, buffer[offset]);
capabilitiesBytesData.setUint8(0, buffer[offset + 1]);
offset += 2;
final capabilityFlags = capabilitiesBytesData.getUint32(0, Endian.big);
// length of auth-plugin-data
int authPluginDataLength = 0;
if (capabilityFlags & mysqlCapFlagClientPluginAuth != 0) {
authPluginDataLength = byteData.getUint8(offset);
}
offset += 1;
// reserved
offset += 10;
Uint8List? authPluginDataPart2;
if (capabilityFlags & mysqlCapFlagClientSecureConnection != 0) {
int length = max(13, authPluginDataLength - 8);
authPluginDataPart2 =
Uint8List.sublistView(buffer, offset, offset + length);
offset += length;
}
String? authPluginName;
if (capabilityFlags & mysqlCapFlagClientPluginAuth != 0) {
authPluginName = buffer.getAsciNullTerminatedString(offset);
}
return MySQLPacketInitialHandshake(
authPluginDataPart1: authPluginDataPart1,
authPluginDataPart2: authPluginDataPart2,
authPluginName: authPluginName,
capabilityFlags: capabilityFlags,
charset: charset,
connectionID: connectionID,
protocolVersion: protocolVersion,
serverVersion: serverVersion,
statusFlags: statusFlags,
);
}
Please do let me know if any additional information is required
It really error packet coming first. Where is on mysql documentation they say that instead of initial handshake, error packet can arrive...
Ok I need to refactor error handling in this library, because right now it is impossible to catch async errors. With this fix I will handle error packets and it will fix this issue too
Yes that's true @zim32. We might want to add some error checking mechanism checks for an error packet and throws the appropriate exception for the same. (For quick reference: https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html)
Thanks for considering the feedback @zim32!
Also, I have resolved the issue on my end by using localhost
instead of directly hardcoding the IP on the same machine. This happened while I was trying to test my Flutter app on my phone. I'm currently facing issues with some timeout related error sent by the server itself (the other issue that I had filed). I assume it's because of some unexpected config. I'll add additional information on that thread for the same soon. Thanks for your valuable time @zim32!
I need some advice. In case of MySQL server sends err packet, should I close connection or leave it open and ready for communication? I can not find any guidance about what to do after receiving error packet...
Hi @zim32,
should I close connection or leave it open and ready for communication? I can not find any guidance about what to do after receiving error packet
Yes, I think it should be done in a safe manner to avoid leaving the library in a bad/unexpected state.
Just did some testing for the same. It seems that the connection anyways closes after the error occurs.
Trying to connect again after this, using the connect
method throws a MySQLClientException
containing the message Can not connect: status is not fresh
.
Trying to disconnect after the that, using the disconnect
method throws a different exception,
Here are the logs for the same:
[ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: Bad state: StreamSink is closed, stack trace: #0 _StreamSinkImpl.add (dart:io/io_sink.dart:134:7)
#1 _Socket.add (dart:io-patch/socket_patch.dart:2193:38)
#2 MySQLConnection.close (package:mysql_client/src/mysql_client/connection.dart:976:13)
#3 disconnect (package:test_project/sql.dart:28:23)
#4 _TestPageState.build (package:test_project/main.dart:42:9)
#5 StatefulElement.build (package:flutter/src/widgets/framework.dart:4919:27)
#6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4806:15)
#7 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4977:11)
#8 Element.rebuild (package:flutter/src/widgets/framework.dart:4529:5)
We might need to make sure that the connection gets safely closed based on the design of library.
It does not close connection after every error right now. MySQL protocol is a mess. Some errors related f.e. to syntax error, should not close connection, I think. Because, why I should close entire connection if it can just continue to make queries? Some errors, mainly logical errors related to bad packet parsing or unexpected packet types should close connection.
Don't know how to do it better
Not really certain about how the protocol is designed, but it does close the connection my end once it shares an error packet (probably done by the server).
Thinking about it again, a bad handshake otherwise too implies that the connection wasn't successful, so it's technically better to close the connection/local stream in case of an error packet during the initial handshake.
Not really sure why does it not close on your end, will need to investigate this further.
If you are able to reproduce this issue on your end, please try calling connect
again and disconnect
to test the behavior.
I am almost done with error handling. There will be an update in readme about it.
Ok. All changes are now in dart pub. Release v0.0.20
Hi @zim32,
The latest release seems to be completely broken on my end unfortunately.
flutter: Error: Null check operator used on a null value
flutter: #0 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:127:25)
#1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:124:26)
#2 Future.doWhile.<anonymous closure> (dart:async/future.dart:702:26)
#3 _rootRunUnary (dart:async/zone.dart:1434:47)
#4 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#6 _CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1281:26)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
<asynchronous suspension>
#9 _CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1281:12)
<asynchronous suspension>
Oh. One moment. Connection is not covered by tests. Need to cover it
Fixed in 0.0.21
Hi @zim32,
Just tested the latest changes. The error is thrown by the library as expected now π
Apart from that,
Not really sure, but I think the error message isn't being parsed correctly. (Reason: The opening single quotes for the message seems to be missing here; and I remember seeing HOST as a part of the error message back then [uncertain if it's a part of the protocol or something]).
flutter: Error: MySQLServerException [1130]: XYZ123' is not allowed to connect to this MySQL server
flutter: #0 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:128:9)
#1 MySQLConnection.connect.<anonymous closure> (package:mysql_client/src/mysql_client/connection.dart:124:26)
#2 Future.doWhile.<anonymous closure> (dart:async/future.dart:702:26)
#3 _rootRunUnary (dart:async/zone.dart:1434:47)
#4 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
#5 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
#6 _CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1281:26)
#7 _rootRunUnary (dart:async/zone.dart:1434:47)
#8 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
<asynchronous suspension>
#9 _CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1281:12)
<asynchronous suspension>
I never encounter incorrect error message parsing. F.e. if I change my username I got proper error message:
MySQLServerException [1045]: Access denied for user 'fake'@'172.18.0.1' (using password: YES)
Oh unsure in that case then.. Could be an issue with my installation of MySQL.
Either ways, I think the required changes have been pushed to the repository (based on the title of the issue) along with making a release for the same, so we could safely close this issue now.
Thanks a lot for coming out with this library and for providing your valuable time and assistance @zim32!
Hm. I think I figured out. This is issue with encoding as usual. I've pushed to main branch. If you can test it, by switchig to main branch it will be super cool
I'm currently trying to connect my Windows Flutter app to a MySQL 8 server hosted on my local machine.
I am able to connect to it via my console, but the same isn't true for the Flutter app. Later found out that this issue was mainly related to not having the correct IP for my device (it was earlier set to the IP of my phone for testing purposes).
This was initially hard to detect, since no logs except a
RangeError
was thrown while reading the packets received from the MySQL server.Here are some logs for the same (have added some additional logging in the library code that might be helpful):
Having a better error handling mechanism by preferably going through some official documentation related would be really helpful to improve the library. (Reference: https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html)
Please do let me know if I could help you'll with a PR for the same.
Thanks for building this library!