Exception Handling in R TclTk

Here we describe just one possible strategy for catching errors in R TclTk applications and displaying them in message boxes. If using R TclTk in Windows, one quickly notices that the RGui main window frequently "gets in the way", as R TclTk windows like to hide behind it. It therefore becomes convenient to bypass RGui altogether and just use a batch file to run Rterm with your R TclTk code. Rather than searching for errors in a .Rout file, it is nicer to see errors pop up as you are running the application.

Try

We define a Try function which tries to evaluate an R expression. If the expression evaluates succesfully, then the expected result is returned. If the expression causes an error, then this error is displayed in a message box.

Try <- function(expr)
{
    if (data.class(result<-try(expr,TRUE))=="try-error")
        tkmessageBox(title="An error has occured!",message=as.character(result),icon="error",type="ok")
    else
        return (result)
}

Try Example

Try(x <- 5)
[1] 5

Try(tkmessageBox("Hello, world!\n"))

We got an error because we should have used:

tkmessageBox(message="Hello, world!\n")

Note that if you want to apply Try to more than one expression at once, you must enclose the expressions within braces.

TryTcl

This error shown above is useful, but we are not interested in reading the first part of the error message for every single "Tcl" error, so we will define a special case of the Try function for TclTk commands. Apologies for not using a more standard method of string-searching within R (perhaps using regular expressions), but I have found the "[tcl]" part of the error message using a C-style string searching function, strstr. R code for this function can be found here.

TryTcl <- function(expr)
{
    if (data.class(result<-try(expr,TRUE))=="try-error")
    {
	    errorMessage <- strstr(as.character(result),"[tcl]")
        tkmessageBox(title="An error has occured!",message=errorMessage,icon="error",type="ok")
    }
    else
        return (result)
}

TryTcl Example

TryTcl(tkmessageBox("Hello, world!\n"))

Failure to Load an R Package

Below is a function which can be used to try to load a package. If the package cannot be found, an error is displayed in a message box.

Require <- function(pkg)
{
    if (data.class(result<-try(.find.package(pkg),TRUE))=="try-error")
    {
        tkmessageBox(title="An error has occured!",message=paste("Cannot find package \"",pkg,"\"",sep=""),icon="error",type="ok")
        return (FALSE)
    }
    else
    {
        require(pkg,character.only=TRUE)
        return (TRUE)
    }
}

Require Example

Require("base")
[1] TRUE
Require("AnotherPackage")
[1] FALSE

Failure to Load a Tcl Package

Below is a function which can be used to try to load/require a Tcl package. If the package cannot be found, an error is displayed in a message box.

TclRequire <- function(tclPkg)
{
  if ((data.class(result<-try(tclRequire(tclPkg),TRUE))=="try-error") || (is.logical(result) && result==FALSE))
  {
    tkmessageBox(title="An error has occured!",message=paste("Cannot find Tcl package \"", tclPkg,
      "\".  To access Tcl/Tk extensions, you must have Tcl/Tk installed on your computer, not just ",
      "the minimal Tcl/Tk installation which comes with R.  If you do have the full Tcl/Tk installed, make ",
      "sure that R can find the path to the Tcl library, e.g. C:\\Tcl\\lib (on Windows) or ",
      "/usr/local/ActiveTcl/lib (on Linux/Unix) or /Library/Tcl on Mac OSX.  To tell R where to ",
      "find the Tcl library, use addTclPath(\"<path to Tcl library>\").\n\n",
      "If using Windows, be sure to read the R for windows FAQ at http://www.stats.ox.ac.uk/pub/R/rw-FAQ.html\n\n",
      "Make sure you have the TCL_LIBRARY environment variable set to the appropriate path, e.g.",
      "C:\\Tcl\\lib\\tcl8.4 and the MY_TCLTK environment variable set to a non-empty string, e.g. \"Yes\".\n\n",
      "The ActiveTcl website is at http://www.activestate.com/Products/ActiveTcl/\n\n",
      "The R Project website is at http://www.r-project.org\n\n",
      "If you need further instructions, please contact your system administrator and consider emailing ",
      "activetcl@listserv.ActiveState.com (for Tcl/Tk help) or r-help@stat.math.ethz.ch (for R help) ",
      "or try browsing through the Help Mailing List archives for a similar question asked previously.",
      sep=""),icon="error",type="ok")
    return(FALSE)
  }
  else
    return(TRUE)
}

TclRequire Example

TclRequire("Tktable")
[1] TRUE
TclRequire("foo")
[1] FALSE