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

Adverb that starts browser() on failure #281

Closed
hadley opened this Issue Jan 11, 2017 · 6 comments

Comments

Projects
None yet
4 participants
@hadley
Member

hadley commented Jan 11, 2017

Like this but in correct environment

hopefully <- function(f) {
  function(...) {
    tryCatch(
      f(...),
      error = function(e) browser()
    )
  }
  
}
@robertness

This comment has been minimized.

robertness commented Jan 11, 2017

You're welcome!

@Deleetdk

This comment has been minimized.

Deleetdk commented Jan 25, 2017

I've been using this function:

try_browse = function(expr) {
  #try
  .trial = try({
    y = eval(substitute(expr), parent.frame())
  })
  
  #catch
  if (inherits(.trial, "try-error")) eval(quote(browser()), parent.frame(n = 1))
  
  y
}

So basically encapsulate the error prone call in that and when it fails, you step right into where you want to be, including when inside implicit loops like ddply or map_df.

I've also suggested trying to make a pipe version of this, but I couldn't figure out how to do that.

@hadley hadley added the feature label Mar 3, 2017

@hadley

This comment has been minimized.

Member

hadley commented Mar 9, 2017

This works:

hopefully <- function(f) {
  function(...) {
    withCallingHandlers(
      f(...),
      error = function(e) {
        # 1: h(simpleError(msg, call))
        # 2: .handleSimpleError(function (e)  <...>
        # 3: stop(...)
        ef <- eval_frame(4)
        eval(quote(browser()), env = ef$env)
      }
    )
  }
}

f <- function(x) {
  y <- 20
  if (x > 5) {
    stop("!") 
  } else {
    x
  }
}

map(1:6, hopefully(f))

But is fragile:

options(warn = 2)
f <- function(x) {
  y <- 20
  if (x > 5) {
    warning("!") 
  } else {
    x
  }
}

map(1:6, hopefully(f))

@lionel- is there a better way here?

@lionel-

This comment has been minimized.

Member

lionel- commented Mar 13, 2017

This doesn't work in ESS because of some limitations of how it handles step-debugging.

I don't think it's that fragile, this just needs another handler for warnings that checks for options("warn"). The R code establishing restarts and handlers hasn't changed for 15 years, so in practice it's not as bad as it feels to just count the frames. Here is a version that works with warnings and in ESS:

hopefully <- function(f) {
  function(...) {
    withCallingHandlers(
      f(...),
      error = function(e) {
        # 1: h(simpleError(msg, call))
        # 2: .handleSimpleError(function (e)  <...>
        # 3: stop(...)
        with_env(frame$env, on.exit({
          browser()
          NULL # Workaround ESS issue
        }))
        return_from(frame)
      },
      warning = function(e) {
        if (getOption("warn") == 2) {
          frame <- eval_frame(7)
          with_env(frame$env, on.exit({ browser(); NULL }))
          return_from(frame)
        }
      }
    )
  }
}
@hadley

This comment has been minimized.

Member

hadley commented Mar 14, 2017

Unfortunately your work around doesn't work in RStudio. I think we'll have to switch based on.Platform$GUI. What does ESS use?

For reasons I don't understand it no longer works when I extract the browser() logic into a separate function:

browse_in_frame <- function(frame) {
  if (.Platform$GUI == "ESS") {
    # Workaround ESS issue
    with_env(frame$env, on.exit({
      browser()
      NULL
    }))
    return_from(frame)
  } else {
    eval(quote(browser()), envir = frame$env)
  }
}
@hadley

This comment has been minimized.

Member

hadley commented Mar 14, 2017

Complete code in #304

hadley added a commit that referenced this issue Mar 14, 2017

@hadley hadley closed this in aea1ce4 Mar 14, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment