Skip to content

OnReceive.Invoke(...) in WebSocketNetProtocol.StartListen() should propagate their exception up rather than failing silently #491

@yt6983138

Description

@yt6983138
  • I am at the right place and my issue is directly related to ROS#. General technical questions I would post e.g. at ROS Answers or Stack Overflow. For library-specific questions I would look for help in the corresponding library forums.
  • I have thoroughly read the Contributing Guideline and writing this issue is the right thing to do in my case.

  • I am using the latest ROS# version available here on the master branch.

  • I am adding all required information, code and data files, screenshots and log files so that you can reproduce the problem.

  • My OS is: Windows 10 22H2

  • My Unity Version is: Not using

  • My ROS Distribution is: Humble

  • My Build Target Platform is: Ubuntu arm64 on xilinx KV260

Here is my bug description:
If the node does not send data in a way that the serializer accepts, the listener in WebSocketNetProtocol fails silently.
I would suggest accepting a logger or logger factory at protocol constructor, and add a try-catch block at line this.OnReceive?.Invoke(this, new MessageEventArgs(memoryStream.ToArray()));, or rethrow this as soon as something is trying to access the protocol.
(The problem is that it would make someone like me to spend hours figuring out why is the subscriber not receiving anything, without a single clue because the exception got swallowed)

Perform the following steps reproduce the bug:
(In my case this was gps blocked from satellite and ros-drivers/nmea_navsat_driver sending data with NaN)

  1. Setup ros-drivers/nmea_navsat_driver with ros2 branch, with a gps module which cannot receive anything
  2. subscribe to /fix
  3. everything blow up after few seconds

Observed results:
Failed silently with no logging nor any exception propagated up
(I copied this from (socket).listener.Exception.InnerException.ToString())

System.Text.Json.JsonException: The JSON value could not be converted to System.Double. Path: $.latitude | LineNumber: 0 | BytePositionInLine: 140.
 ---> System.InvalidOperationException: Cannot get the value of a token type 'Null' as a number.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedNumber(JsonTokenType tokenType)
   at System.Text.Json.Utf8JsonReader.TryGetDouble(Double& value)
   at System.Text.Json.Utf8JsonReader.GetDouble()
   at System.Text.Json.Serialization.Converters.DoubleConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Utf8JsonReader& reader, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
   at RosSharp.RosBridgeClient.MicrosoftSerializer.Deserialize[T](String json)
   at RosSharp.RosBridgeClient.Subscriber`1.ReceiveThreadSafe(String message, ISerializer serializer)
   at RosSharp.RosBridgeClient.Subscriber`1.Receive(String message, ISerializer serializer)
   at RosSharp.RosBridgeClient.RosSocket.Receive(Object sender, EventArgs e)
   at RosSharp.RosBridgeClient.RosSocket.<.ctor>b__12_0(Object sender, EventArgs e)
   at RosSharp.RosBridgeClient.Protocols.WebSocketNetProtocol.StartListen()

Expected results:
Some exception propagated up, or the listener continue running, accepting other topic messages

Relevant Code:

var socket = new(new WebSocketNetProtocol("address"));
socket.Subscribe<NavSatFix>("/fix", gps =>
{
	//this._logger.LogDebug("Received GPS data: {gps}", gps.MemberToString());
}, ensureThreadSafety: true);

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions