Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test for infinite recursion error? #1944

Open
mmuurr opened this issue Mar 14, 2024 · 3 comments
Open

Test for infinite recursion error? #1944

mmuurr opened this issue Mar 14, 2024 · 3 comments

Comments

@mmuurr
Copy link

mmuurr commented Mar 14, 2024

As part of developing a package there's a specific pattern I want to detect that leads to an infinite recursion error. (If this error ever doesn't happen, then it's likely I broke something in the logic, hence my desire to test for it.)

This test fails:

f <- function() f()
expect_error(f())
# Error: C stack usage 9522952 is too close to the limit

This passes, but is a bit clunky:

f <- function() f()
tryCatch({
  f()
  TRUE
}, error = \(e) {
  FALSE
}) |> expect_false()

Should that first expect_error() test fail, given that the second passes?

({testthat} v3.2.1)

@MichaelChirico
Copy link
Contributor

@mmuurr I agree this looks like a {testthat} bug. For some reason that class of error is not caught. FWIW I might simplify/tighten your workaround as follows:

expect_s3_class(tryCatch(f(), stackOverflowError=identity), "error")

@hadley
Copy link
Member

hadley commented Apr 17, 2024

IIRC. this is trickier than it looks because if you've run out of stack space, it's possible that no other code will work. So I'm a bit sceptical we can make this work generally, but @lionel- might know more.

@lionel-
Copy link
Member

lionel- commented Apr 18, 2024

We generally rely on calling error handlers, i.e. ones that run without unwinding the call stack first. These calling handlers are purposefully not run in the case of a R-level stack overflow error to prevent R from crashing from an actual C-level stack overflow.

We could do something like rlang::try_fetch() which wraps the withCallingHandlers() call in tryCatch(stackOverflowError = ) to catch these.

Or much easier than changing all our condition handling machinery, provide a dedicated expect_no_stack_overflow() for this specific case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants