Skip to content

Instantly share code, notes, and snippets.

@ryan-heslin
Created January 3, 2022 23:56
Show Gist options
  • Select an option

  • Save ryan-heslin/d46037c97f3dc8f435ff01a45f792a19 to your computer and use it in GitHub Desktop.

Select an option

Save ryan-heslin/d46037c97f3dc8f435ff01a45f792a19 to your computer and use it in GitHub Desktop.

Revisions

  1. ryan-heslin created this gist Jan 3, 2022.
    41 changes: 41 additions & 0 deletions search_error.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    Friendly error messages are unfortunately not one of R's strengths. Often, running buggy code will yield something like:

    ```r
    DF <- subset(mtcars, cyl > 4)
    df$mpg <- round(df$mpg)

    #> Error in df$mpg : object of type 'closure' is not subsettable
    ```
    Huh? A closure is an R function with an enclosing environment (that is, one that can access the environment where it was defined).
    `df` is one such function, which gives the F distribution. In plain English, the error message is saying you can't extract an element from a function as if it were a vector.

    But how many R novices who run into this error for the first time can figure that out on their own? (I certainly couldn't!). Then the only
    way out is to Google the error message and find an explanation. But copying the code into a web browser breaks focus and wastes time. We can
    automate that task.

    First, define a function to Google a query from within R, which is suprisingly simple:

    ```r
    google <- function(query) {
    browseURL(paste0("http://www.google.com/search?q=", query))
    }
    ```

    We just have to create a query URL and send it to `browseURL`. Extracting the error message is a little more involved, but not too bad:

    ```r
    # Google most recent error message
    search_error <- function(stackoverflow = TRUE) {
    if ((error <- capture.output(cat(geterrmessage()))[1]) == "") {
    cat("No error messages in buffer")
    return()
    }
    google(paste(error, ifelse(stackoverflow, "site:stackoverflow.com", "")))
    }
    ```
    `geterrmessage` does...pretty much that. `capture.output` and `cat` get the text without the ending newline. Error messages can have
    length greater than 1 (a lot of `tidyverse` error messages are like that), so I subset only the first element to capture the most essential
    information. The rest is details: an `if` clause to abort if there are no recorded errors (if only!), and an argument letting you restrict
    the search to StackOverflow.

    I hope these functions relieve some of the tedium of debugging.