hacker-cb / modbus-dart

BSD 3-Clause "New" or "Revised" License
36 stars 22 forks source link

No able to catch MODBUS ERRORS Exceptions #26

Open saguado69 opened 1 year ago

saguado69 commented 1 year ago

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()); }

ElegantCrab commented 1 year ago

This error is related to the error I was having and fixed here #29

dg76 commented 5 months ago

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.