nauful / LibUA

Open-source OPC UA client and server library
Apache License 2.0
262 stars 94 forks source link

Exception in background thread causing process to terminate #189

Closed 2sComplement closed 1 month ago

2sComplement commented 2 months ago

Hello, and thanks for your work on this library.

As the title says, I'm running into an intermittent issue where a socket exception on a background thread is causing an application crash:

Unhandled exception. System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
   at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
   at LibUA.Client.CloseConnection()
   at LibUA.Client.ThreadTarget()

It seems like the server is forcing the connection closed from its end during or before the call to CloseConnection(), causing this exception to be thrown. My problem is that I have no way of catching this exception.

What is the recommended way of handling this? Ideally I could catch this exception and recreate my client.

nauful commented 2 months ago

Glad this library has been helpful for you.

I've updated the client code to no longer throw SocketExceptions. It should instead actively return either a bad status code or throw an exception when you call a method on a closed client. Try the latest and let me know how that works for your case.

2sComplement commented 2 months ago

Thanks! I will try it out and let you know in a day or so, since the issue was intermittent but not infrequent.

Do you think it would be worth having a way for consumers to optionally provide their own exception handlers for exceptions thrown in the background thread?

2sComplement commented 1 month ago

I have not seen this issue since upgrading, so it seems like your fix is working. The exception is almost certainly being swallowed though which feels wrong, hence my question about providing an exception handler. Any thoughts on that? I'm happy to submit a PR if that helps!

nauful commented 1 month ago

There's no straightforward way to collect async exceptions in .NET. You'll get either an error status code or an exception if you try to call any methods on a client with a closed connection now, and given that you can catch that synchronously, you can reopen the connection at that point.