0

I have C code that uses Tcl/Tk library. I then create a library using this C code which is then linked to R language package. I have a function in the C code:

int doSomething(){
   if(TRUE){
      return TCL_OK;
   else{
      TCL_RESULT3("Error")
      return TCL_OK;
}

Currently, I use TCL_RESULT3("Error") in the C code, and then in R check if result <- tclvalue(tcl(...)) #calls doSomething() returns a string with Error:

if (startsWith(result, "Error"))
        {
            return(FALSE)
        }
        return(TRUE)

and base further actions in R on the returned value.

However, even though there is an error, I still call TCL_OK because TCL_ERROR produces something that R cannot seem to handle (at least it is not straightforward). My question is if it is possible to restructure my function as:

int doSomething(){
   if(TRUE){
      return TCL_OK;
   else{
      return TCL_ERROR;
}

and have R understand what is being returned. Currently, if TCL_OK is returned, then result will be an empty string "". If TCL_ERROR is returned, then result will yield: Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] . which R does not know how to handle.

Is it possible to have R handle such an error (i.e. return a value of FALSE if this error pops up) or is checking for an error message using TCL_RESULT3() in conjunction with TCL_OK the best method for such a process?

hkj447
  • 677
  • 7
  • 21

1 Answers1

1

When your C code returns TCL_ERROR (instead of TCL_OK) that's an error condition, which is logically like an exception in other languages. Can R handle those? Yes (apparently; I know very little R). Here's one way (there are others, of course; the right choice depends on what you're doing and the likely cause of the exception).

result <- tryCatch(
    {
        # This is where you put in the code to call into Tcl
        tclvalue(tcl(...)) # calls doSomething()
    },
    error = function(err) {
        message(paste("error occurred in Tcl code:", err))
        return(NaN)   # Need an alternative result value here
    }
)

Note that if you're calling an arbitrary Tcl command, you pretty much have to handle exceptions. Failures are a fact of life, and you need to allow for them in robust code.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • 1
    Some types of error might be better handled on the Tcl side of course. There there's a fairly sophisticated `try` command to help out. It's logically similar to `tryCatch()` in R, but more adapted to the way a different language works. There's also an older `catch` command, but that really does expose some peculiarities. – Donal Fellows Jul 04 '20 at 09:04