No able to catch MODBUS ERRORS Exceptions
Opened this issue · 2 comments
Hi,
I'm having an issue when I disconnect the modbus server. An exception is generated but I'm not able to catch it. My code is wrapped with a try catch but the Exception is raised but bot catches by my code. These are the exceptions I'm trying to catch:
Unhandled Exception: ModbusConnectException (MODBUS ERROR: Connector was closed before operation was completed)
Unhandled Exception: SocketException: Connection reset by peer (OS Error: Connection reset by peer, errorno = 54
My app works fine, it connect correctly, reconnect, readRegisters, etc, but whenever I switch off manually my modbus server, I'm not able to catch the exception. So, thanks in advance for your support.
And this is my code:
try {
isConnecting = true;
event = 'Connecting ... $host:$port';
client = modbus.createTcpClient(
host,
port: port,
mode: modbus.ModbusMode.rtu,
timeout: const Duration(seconds: 10),
);
await client.connect().then((value) {
isConnected = true;
isConnecting = false;
event = 'Connected to $host:$port';
int slaveId = 1;
polling =
Timer.periodic(const Duration(milliseconds: 200), (Timer t) async {
isPolling = true;
client.setUnitId(slaveId);
await client
.readHoldingRegisters(0x0001, 100)
.then((registers) {
debugPrint('REGS: ${registers.toString()}');
})
.timeout(const Duration(seconds: 5))
.onError((error, stackTrace) {
polling.cancel();
isConnected = false;
isPolling = false;
event = 'Disconnected from $host:$port';
return;
});
});
return isConnected;
});
} on modbus.ModbusConnectException catch (error) {
debugPrint(error.toString());
} on SocketException catch (error) {
debugPrint(error.message);
} on Error catch (error) {
debugPrint(error.toString());
} catch (error) {
debugPrint(error.toString());
}
This error is related to the error I was having and fixed here #29
I have the same problem and I think it is caused by this code:
responseCompleter.future.whenComplete(() {
if (_waitingQueue.isNotEmpty) {
var request = _waitingQueue.removeFirst();
_sendNext(request);
}
});
In my case it crashes in "_sendNext":
Bad state: StreamSink is closed
#0 _StreamSinkImpl.add (dart:io/io_sink.dart:134:7)
#1 _Socket.add (dart:io-patch/socket_patch.dart:2233:38)
#2 TcpConnector.write (package:modbus/src/tcp_connector.dart:91:14)
#3 ModbusClientImpl._sendData (package:modbus/src/client.dart:87:16)
#4 ModbusClientImpl._sendNext (package:modbus/src/client.dart:123:5)
#5 ModbusClientImpl._executeFunctionImpl.<anonymous closure> (package:modbus/src/client.dart:108:11)
#6 _RootZone.run (dart:async/zone.dart:1654:54)
#7 _FutureListener.handleWhenComplete (dart:async/future_impl.dart:190:18)
#8 Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:737:39)
The problem is that "whenComplete" has no "catchError" block and is executed outside of the normal Future chain. It seems that it would require an additional exception handling like this:
someFutureOperation()
.then((value) {
// Handle success
})
.catchError((error) {
// Handle errors from someFutureOperation
})
.whenComplete(() {
// Code that should run after someFutureOperation completes, either successfully or with an error.
// If this code throws, it won't be caught here.
}).catchError((error) {
// This will catch exceptions thrown from within `whenComplete` as well as from `someFutureOperation`.
});
I will try to ignore the error now by catching it outside of my main function:
void main() {
runZonedGuarded(() {
runApp(MyApp()); // Replace with your Flutter app
}, (error, stackTrace) {
print('Unhandled exception caught: $error');
// Handle the error here (e.g., logging)
});
}
Because that's the only way to catch this exception without modifying the library.