JuliaInterop / RCall.jl

Call R from Julia
Other
318 stars 59 forks source link

If julia functions which was brought to R throws an error, no real error is thrown, but an error object is returned #216 #508

Open schlichtanders opened 7 months ago

schlichtanders commented 7 months ago

I created an issue at JuliaCall however after a first inspection, I think it is actually an RCall issue.

Concretely something in the following is not raising julia errors when run on R. Also the stacktrace is not reported. https://github.com/JuliaInterop/RCall.jl/blob/69c22ddc91a69d3411fa282652bbe00b5d4bdea4/src/callback.jl#L122-L147

Helpful steps to provide error support

Looking into JuliaCall's error handling, there are two places:

  1. on JuliaCall julia side the following try catch converts a julia error to an R object https://github.com/Non-Contradiction/JuliaCall/blob/c05473bea78a0197c639f7e82ab1c6f2e943e1cc/inst/julia/setup.jl#L165-L194

    function docall(call1)
    try
        # ...
    catch e
        Rerror(e, stacktrace(catch_backtrace())).p;
    end;
    end
  2. on JuliaCall R side the following intercepts these R objects and raises them as R errors https://github.com/Non-Contradiction/JuliaCall/blob/c05473bea78a0197c639f7e82ab1c6f2e943e1cc/R/interface.R#L76-L78

    r <- .julia$do.call_(jcall)

    if (inherits(r, "error")) stop(r)

Both these steps would need to be replicated inside the conversion of a Julia Function to an R function.

schlichtanders commented 7 months ago

I found where the julia error object is transformed into a simpleError, skipping stacktrace entirely

https://github.com/JuliaInterop/RCall.jl/blob/69c22ddc91a69d3411fa282652bbe00b5d4bdea4/src/callback.jl#L61

this should be changed to the RCall equivalent of JuliaCall's

err = Rerror(e, stacktrace(catch_backtrace())).p;
schlichtanders commented 7 months ago

The second step needed is to surround the following with the if (inherits(r, "error")) stop(r) logic

https://github.com/JuliaInterop/RCall.jl/blob/69c22ddc91a69d3411fa282652bbe00b5d4bdea4/src/callback.jl#L132-L135

Unfortunately, I couldn't find a way yet how to add such if else logic from Julia.

schlichtanders commented 7 months ago

I fixed the one part for me now, but it seems juliaCallback cannot be fixed outside of RCall itself.

As soon as I call setup_callbacks() again and run a typical failing example

julia_eval('() = error("fail")')()

I get the following error (or sometimes also a Segmentation fault)

ERROR: UndefVarError: `error_msg` not defined

I bet this has something todo with creating C functions and would be solved if this is officially fixed in RCall.jl