Error in callback leaves WebSocket object in non-responsive state
wch opened this issue · 1 comments
Example:
ws <- websocket::WebSocket$new("ws://echo.websocket.org")
ws$onMessage(function(event) {
message("Message received: ", event$data)
stop("error here")
})
ws$send("hello")
#> Message received: hello
#> later: exception occurred while executing callback:
#> Evaluation error: Evaluation error: error here..
ws$send("hello") # Nothing happens
In my testing, it looks like there are two problems. The callback is invoked from the later event loop. The R code at https://github.com/rstudio/websocket/blob/3f27afd2/R/websocket.R#L244 calls wsPoll
, which is a wrapper for the wsPoll
C++ function, which calls handleMessage
, which calls the invoke
R function, which calls the user-defined onMessage
callback.
If that R code throws an exception, the exception bubbles up from R to C++ to the R handleIncoming
method, and private$scheduleIncoming
doesn't get called.
Even if that's fixed by adding a tryCatch
around the wsPoll(private$wsObj)
, it appears that the websocket on the C++ side ends up in a messed up state when an exception occurs, either in the R user code or in an exception that's thrown directly in C++. I don't understand the websocketpp code well enough to say why this is happening.
Basically, the structure of the calls is:
later calls R handleIncoming
function -> calls C++ poll
function -> (mystery stuff) -> calls C++ handleMessage
function -> calls R invoke
function -> calls R user callback.
If the error happens in the (mystery stuff) layer, then the websocket seems like it ends up in a state where it no longer works properly.
I think the solution is to catch the error in either the R invoke
function or the C++ `handleMessage function.