[R-pkg-devel] tryCatch() doesn't capture errors due to && or || with R CMD check --as-cran

Lionel Henry ||one| @end|ng |rom r@tud|o@com
Thu Sep 1 18:47:36 CEST 2022


Hi Martin,

I'm not sure I understand what you mean regarding suppressed warnings
in testthat.

- All warnings are reported to users by `devtools::test()`, with
  accompanying backtraces. They are not hidden.

- R CMD check doesn't report warnings emitted from files in `tests/`.

If you need some sort of warning to surface as errors, warnings, or
notes in R CMD check, it should be possible to come up with
something. This could take the form of special classes of conditions
that R CMD check would catch and emit corresponding diagnostics
for. We would change testthat to make sure all such conditions are
properly emitted during checks.

Best,
Lionel


On 9/1/22, Martin Maechler <maechler using stat.math.ethz.ch> wrote:
>>>>>> Etienne Bacher
>>>>>>     on Thu, 01 Sep 2022 13:55:15 +0000 writes:
>
>> Dear all,
>
>> Calling && or || with LHS or (if evaluated) RHS of length greater than one
>> gives an error in the devel version of R and a warning since R 4.2.0. With
>> R 4.2.1, I can capture this warning with tryCatch(). However, R CMD check
>> with R-devel fails because of this new behavior, meaning that tryCatch()
>> doesn't work.
>
> Very much on purpose, even though we (the R Core team) may not
> have said so loudly.
>
> The problem is that too many "smart" people, including the
> authors of certain widely used testing packages do call
> tryCatch(), or suppressWarnings() and similar to eliminate
> warnings and errors in a situation we really *do* want these to
> be shown.
>
> For instance, we, the Matrix package authors, have planned to
> deprecate certain usages of  as(*, "<someMatrixClass>")  and
> give deprecation warnings -- see  help(Deprecated) -- so the
> users and package authors can see the undesired usages and
> eventually update their code.
>
> No, because of too much use of suppressWarnings() they *NEVER
> EVER* see *any* deprecation warnings for all their own code
> which silences these warnings and for all (often 100%) of their
> tests where they use the famous test...t  package ...
>
> An additional reason for such a non-suppressible error is that
> when you find such warnings/errors in package testing of
> packages with many dependencies, if the warning/error is raised
> and you *do* see it, it may *still* not at all be easy to see
> from which of the (sometimes 20--100) packages that are in use
> the problem is caused.
>
> I hope you understand that such "obnoxious" behavior is
> rational and desirable in such rare cases.
>
> Best regards,
> Martin
>
>
> --
> Martin Maechler
> ETH Zurich  and  R Core team
>
>> For example, take this function:
>>
>> foo <- function() {
>>   tryCatch(
>>     if (c(TRUE, TRUE) || c(TRUE, TRUE)) 1,
>>     warning = function(w) {
>>       print(w)
>>       NULL
>>     },
>>     error = function(e) {
>>       print(e)
>>       NULL
>>     }
>>   )
>> }
>>
>> With R 4.2.1, this correctly gives a warning and returns NULL when I run
>> this locally:
>> > foo()
>> <simpleWarning in c(TRUE, TRUE) || c(TRUE, TRUE): 'length(x) = 2 > 1' in
>> coercion to 'logical(1)'>
>> NULL
>>
>> And if I change the environment variables to return an error instead of
>> the warning, it correctly gives an error and returns NULL:
>> > Sys.setenv(
>>     `_R_CHECK_LENGTH_1_CONDITION_` = "true",
>>     `_R_CHECK_LENGTH_1_LOGIC2_` = "true"
>> )
>> >foo()
>> <simpleError in c(TRUE, TRUE) || c(TRUE, TRUE): 'length(x) = 2 > 1' in
>> coercion to 'logical(1)'>
>> NULL
>>
>> This behavior is expected. But if I put this function in a package, add a
>> test for it, and run R CMD check "." --as-cran (or
>> rcmdcheck::rcmdcheck(args = "--as-cran")), then I get an error that I
>> paste at the end of this email because it's quite long. I thought that
>> tryCatch() would capture this error, even when using R CMD check with
>> R-devel, but this is not the case. Is this an expected behavior or a bug?
>>
>> If you want to reproduce this error, I made a tiny package here:
>> https://github.com/etiennebacher/testpackage. You can simply clone the
>> repo and run R CMD check on it.
>>
>> If it matters, I'm using R 4.2.1 on Windows 10.
>>
>> Thanks in advance,
>>
>> Etienne
>>
>>
>>  ----------- FAILURE REPORT --------------
>>  --- failure: length > 1 in coercion to logical ---
>>  --- srcref ---
>> :
>>  --- package (from environment) ---
>> compiler
>>  --- call from context ---
>> do.call(ffun, args)
>>  --- call from argument ---
>> .Primitive("||")(c(TRUE, TRUE), c(TRUE, TRUE))
>>  --- R stacktrace ---
>> where 1: do.call(ffun, args)
>> where 2: mode(e)
>> where 3: mode(e) %in% constModes
>> where 4: checkConst(do.call(ffun, args))
>> where 5: doTryCatch(return(expr), name, parentenv, handler)
>> where 6: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>> where 7: tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
>> where 8: doTryCatch(return(expr), name, parentenv, handler)
>> where 9: tryCatchOne(tryCatchList(expr, names[-nh], parentenv,
>> handlers[-nh]),
>>     names[nh], parentenv, handlers[[nh]])
>> where 10: tryCatchList(expr, classes, parentenv, handlers)
>> where 11: tryCatch(checkConst(do.call(ffun, args)), error = function(e)
>> NULL,
>>     warning = function(w) NULL)
>> where 12: constantFoldCall(e, cntxt)
>> where 13: constantFold(test, cntxt, loc = cb$savecurloc())
>> where 14: h(e, cb, cntxt)
>> where 15: tryInline(call, cb, cntxt)
>> where 16: cmpCall(e, cb, cntxt)
>> where 17: cmp(e, cb, cntxt, setloc = FALSE)
>> where 18: genCode(a, pcntxt, loc = cb$savecurloc())
>> where 19: cb$putconst(genCode(a, pcntxt, loc = cb$savecurloc()))
>> where 20: cmpCallArgs(args, cb, cntxt, nse)
>> where 21: cmpCallSymFun(fun, args, call, cb, cntxt)
>> where 22: cmpCall(e, cb, cntxt)
>> where 23: cmp(subexp, cb, cntxt, setloc = FALSE)
>> where 24: h(e, cb, cntxt)
>> where 25: tryInline(call, cb, cntxt)
>> where 26: cmpCall(e, cb, cntxt)
>> where 27: cmp(e, cb, cntxt, setloc = FALSE)
>> where 28: genCode(body(f), ncntxt, loc = loc)
>> where 29: cmpfun(f)
>> where 30: doTryCatch(return(expr), name, parentenv, handler)
>> where 31: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>> where 32: tryCatchList(expr, classes, parentenv, handlers)
>> where 33: tryCatch(cmpfun(f), error = function(e) {
>>     notifyCompilerError(paste(e$message, "at", deparse(e$call)))
>>     f
>> })
>> where 34: compiler:::tryCmpfun(function ()
>> {
>>     tryCatch(if (c(TRUE, TRUE) || c(TRUE, TRUE))
>>         1, warning = function(w) {
>>         print(w)
>>         NULL
>>     }, error = function(e) {
>>         print(e)
>>         NULL
>>     })
>> })
>> where 35: lazyLoadDBinsertVariable(vars[i], from, datafile, ascii,
>> compress,
>>     envhook)
>> where 36: makeLazyLoadDB(ns, dbbase, compress = compress, set.install.dir
>> = set.install.dir)
>> where 37: code2LazyLoadDB(package, lib.loc = lib.loc, keep.source =
>> keep.source,
>>     keep.parse.data = keep.parse.data, compress = compress,
>> set.install.dir = set.install.dir)
>> where 38: tools:::makeLazyLoading("testpackage",
>> "C:/Users/etienne/AppData/Local/Temp/Rtmp8QXtOL/file41b43ee61605/testpackage.Rcheck/00LOCK-TESTPA~1/00new",
>>
>>     keep.source = FALSE, keep.parse.data = FALSE, set.install.dir =
>> "C:/Users/etienne/AppData/Local/Temp/Rtmp8QXtOL/file41b43ee61605/testpackage.Rcheck/testpackage")
>>
>>  --- value of length: 2 type: logical ---
>> [1] TRUE TRUE
>>  --- function from context ---
>> function (what, args, quote = FALSE, envir = parent.frame())
>> {
>>     if (!is.list(args))
>>         stop("second argument must be a list")
>>     if (quote)
>>         args <- lapply(args, enquote)
>>     .Internal(do.call(what, args, envir))
>> }
>> <bytecode: 0x0000021b0a155e20>
>> <environment: namespace:base>
>>  --- function search by body ---
>> Function do.call in namespace base has this body.
>>  ----------- END OF FAILURE REPORT --------------
>> Fatal error: length > 1 in coercion to logical
>>
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>



More information about the R-package-devel mailing list