When writing R extensions using Rcpp is it possible to get more information when an exception is thrown?
For instance by default when an index is out of bound I get:
Error in myfunction(V) :
index out of bounds
Calls: source ... eval -> myfunction -> .Call -> cpp_exception
Execution halted
at this point I have no idea where in the code it might have happened. When compiling the code with debug information is it possible to print the stack? Can the Rcpp exception do that?
On a segfault I guess I can try to use deathhandler, but I am also looking for a solution for regular exceptions.
That one is most likely not from your code / Rcpp code.
If you use Rcpp for exception, you coontrol the and recover the message at the R level (provided you derive from std::exception etc). There a number of example out there as e.g. this SO post.
But to catch 'random' errors like this, you may need to resort to using the debugger.
Related
When working in RStudio (version 0.99.482 and 1.0.136), if I source a file and an error occur I just get the error message without any context. If the file is longer than a few lines of code, that informaiton is largely useless. What I want to know when an error occurs is the following:
What function threw the error? Preferably what function I called from my script, not something burried deep inside a package.
On what line of my file did the error occur?
This seems like a very basic thing for a scripting language to do, but yet I am unable to find an easy solution. Yes, I am aware of the traceback() function, but (a) it is a hassle to call it every time there is an error, and (b) the output is massive and not that helpful.
I am building an R package and have several files containing only class definitions (R6Classes, but I'm sure this applies to any kind). On building the package, I get an error due to some definitions not being found - e.g. the files are not loaded in the necessary order:
Error in R6Class("MyChildClass", inherit = DataSource,
public = list(initialize = function(...) {
(from MyChildClass.R#1) :
object 'DataSource' not found
Calls: <Anonymous> ... source_many -> source_one
-> eval -> eval -> R6Class
Execution halted
Exited with status 1.
I know about the Collate: field in DESCRIPTION, but there I have to write down every single .R file in the package. This is very cumbersome as the project grows in size...
Two other options occur to me:
Either put the starting-function in a file at the lexical end of the line (Z_Evaluate.R)
or wrap all class definition file (<FileName>) contents inside their own load function (LoadClassDefinitionsFrom<FileName>()) and call them at the beginning of the startup function in correct order.
Both don't really seem very convenient to me. If I'm not mistaken, the Latex compiler goes through the source twice in order to get everything right. That's probably not doable within R.
What's the best practise to deal with such a problem?
In order to aid myself with displaying debugging information, I decided to create the following tiny function that would dynamically switch between displaying data in RStudio's internal data browser and simple character-based output, depending on capabilities of the platform, where my modules are being sourced at:
View <- function (...) {
if (.Platform$GUI == "RStudio")
View(...)
else
print(...)
}
This function is located, along with other utility functions, in the module <PROJ_HOME>/utils/debug.R. All modules that need these functions, include it via source("../utils/debug.R").
Running my project's code on my Amazon EC2 instance's Linux console is fine. However, running it on the same virtual machine via RStudio Server results in the following error message:
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Error during wrapup: evaluation nested too deeply: infinite recursion / options(expressions=)?
It seems to me that R gets confused as to which View() function needs to be called. Initially, I assumed that RStudio overloads the utils::View() and I tried to call it explicitly, but it failed. Then I thought that RStudio somehow defines its View() implementation in global environment, so that it just needs to be called View() without package/library reference. However, as I you see, it doesn't work either. Another potential reason of the error might be that I overestimated the "smartness" of R in terms of my use of ... arguments.
So, what is wrong and how to fix it?
RStudio hooks the View function. One approach might be to see if anyone has overridden the View function from utils, and to call the override if it exists. What about this?
View <- if (identical(utils::View, View)) print else View
I have a longer, complex code (>7000 lines) with many nested functions, each of them enclosed in a separate tryCatch. The code works perfectly except for a "pseudo-error":
Error in doWithOneRestart(return(expr), restart): no function to return from, jumping to top level
doWithOneRestart() is internal in R as an element of the tryCatch function. I call it "pseudo-error", because the tryCatch should lead to stop() if an error ocurrs and write the error message in a log file. Instead, this "error" is not stopping the program (actually not influencing it at all) and it is shown only on the console and not written into the log file. Usual debugging procedures did not help, because the error is not reproducible (!): it may ocurr at different processing stages of the program. Changing the warning options to 0 or -1 will not help.
Since the program does the job, this error is not critical. But I would like to understand what is happening. Maybe someone has already experienced the same problem, or could come up with an original debugging strategy ...
Update (28.10.2013):
I found out where the problem came from. It's linked to a problem with java heap overflow (I was using the xlsx package to read Excel files). Among many other problems: although the connection to the Excel file is closed (definitely!), the system considers it as an unused connection (shown in traceback()), tries to close it, but finds out it is already closed: you get the "pseudo-error" described above, and never exactly at the same moment (not reproducible). Using the garbage collector gc() at the right place solved the problem. The script is now running stable for several days.
Advice from Peter Dalgaard on R-help.
The easiest way to get that message is to execute return() from the
top level:
return(1)
You might be trying to return() from source()d file. Or maybe
source()ing something that was intended to be inside a function body
(extraneous '}' characters can do that).
The usual debugging strategies should work: calling traceback() after the error, or setting options(error = recover).
Is it possible to detect if there was a problem when running roxygenize (package roxygen2)?
I want to automate the process documenting, checking and building a package, and would like to stop when documenting goes wrong.
The roxygenize help says the return value is NULL, and I searched stackoverflow without success. Currently, I need to look at the output and search if there was a line starting with "Error".
Any hint appreciated!
When roxygenize finds an error, for example, you included stop("Raise an error") in your code, then roxygenize will return an error.
The other scenario (which is what you are getting at), is that roxygenise is able to finish, but some aspects of the documentation process are incorrect. In this case, these errors are stored as warnings. So one solution is to change warnings to errors.
For example, suppose you had a file containing the line:
#' #XXX
This would cause:
roxygenise("pkg/")
to raise a warning
Warning: XXX is an unknown key in block AllGenerics.R:5
If we changed warnings to errors:
##All warnings are now errors
options(warn=2)
Then
roxygenise("pkg/")
would raise the error:
Error: (converted from warning) XXX is an unknown key in block AllGenerics.R:5
You can then use the standard tryCatch technique for dealing with errors.