Error reading data from socket.tcp connection

The code:

            local s, status, partial = tcp:receive()

The error being thrown:

Lua: deserialize error: invalid value: byte array, expected a string
Traceback:
stack traceback:
	[C]: in function 'coroutine.yield'
	[string "coroutine"]:9: in function 'wrapped_coroutine_resume'
	[string "cosock.lua"]:265: in field 'run'
	[string "st/driver.lua"]:739: in method 'run'
	[string "init.lua"]:39: in main chunk

Funnily enough it was not throwing this error yesterday from the same device but is throwing the error today… Not sure if it is a code change I made or the value changed on the device today (could be some date stamp related bytes).

The value being read when this error is thrown:

1 $ctb?G@=iR;0???s㉱

The data is apparently in codepage cp437, and I don’t really care about this string, but I am unable to ignore this line as the entire code collapses here.

Is there a way to read bytes instead of strings so this kind of thing can be ignored in my code?

Also, if I use socket.tcp instead of cosock, I get the error

attempt to call a nil value (method 'receive')

@nayelyz 10 chars

1 Like

@RBoy I am curious what this message means :slight_smile:

I’m tagging @nayelyz who’s the support rep that can investigate and create tickets for the ST devs if required to fix the issue with the libraries.

10 chars - is a filler because the forum requires atleast 10 chars to post anything

1 Like

Hi, @schwark

I already asked the team about this. I’ll come back once I get their feedback.

Following up on this issue:

@schwark, could you share the snippet code to see the usage of the socket, please? The call to tcp:receive() doesn’t provide enough information.
If you don’t want to share it here, you can send it privately to us over DM or to build@smartthings.com.

It is not the call to tcp:receive, that is the issue. It is the DATA being read from the socket… I will send the entire data being read from socket (taken from a telnet session) in a DM. That specific line that has binary data is tripping the receive call… The receive call itself is working fine when there is no binary data. Also, as I mentioned, it started failing yesterday, but was working the day before for some reason, but the binary data itself may have changed in the device in that time.

It turns out it is not the socket read, but my debug line trying to convert byte array to string via tostring() that was causing the error. So the issue was that tostring(byte array) causes a FATAL error.

ah, this is a native function of Lua. According to the documentation, it accepts any value:
https://www.lua.org/manual/5.3/manual.html#pdf-tostring
But, this issue indicates another thing…

Following up on this, @schwark
The team mentioned the following:

Strings in Lua can contain characters with any numerical value which means that any binary data can be stored in a string. However, when non-UTF-8 characters are attempted to be logged, it causes a deserialization error because it is not a readable string. If you want the binary data to be printed then we think you will need to do something like this:

--convert received binary string to table of numerical bytes
local bytes = { string.byte(received_binary_string, 0, -1) }
--convert numerical bytes to UTF-8 string 
local byte_str = table.concat(bytes, ', ')

Please, let us know your results.

1 Like