Skip to content

Commit

Permalink
Wrap glue errors, if possible (#294)
Browse files Browse the repository at this point in the history
Fixes #229
  • Loading branch information
hadley authored Nov 28, 2023
1 parent 887fb75 commit db9b656
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 4 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Suggests:
dplyr,
knitr,
magrittr,
rlang,
rmarkdown,
RSQLite,
testthat (>= 3.2.0),
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# glue (development version)

* If rlang is installed, glue will generate more informative errors if an
interpolated expression either can't be parsed or fails to evaluate (#229).

* `+` now works in more situations, and gives errors when one side isn't a
character vector. It no longer automatically applies glue interpolation to
a non-glue input, if there is one. You'll need to do that yourself (#286).
Expand Down
4 changes: 2 additions & 2 deletions R/sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ sql_quote_transformer <- function(connection, .na) {
is_quoted <- any(m[[1]] != -1)
if (is_quoted) {
regmatches(text, m) <- ""
res <- eval(parse(text = text, keep.source = FALSE), envir)
res <- identity_transformer(text, envir)

if (length(res) == 1) {
res <- DBI::dbQuoteIdentifier(conn = connection, res)
Expand All @@ -222,7 +222,7 @@ sql_quote_transformer <- function(connection, .na) {
res[] <- lapply(res, DBI::dbQuoteIdentifier, conn = connection)
}
} else {
res <- eval(parse(text = text, keep.source = FALSE), envir)
res <- identity_transformer(text, envir)
if (length(res) == 0L) {
if (should_collapse) {
return("")
Expand Down
28 changes: 26 additions & 2 deletions R/transformer.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@
#' @seealso `vignette("transformers", "glue")` for documentation on creating
#' custom glue transformers and some common use cases.
#' @export
identity_transformer <- function(text, envir) {
eval(parse(text = text, keep.source = FALSE), envir)
identity_transformer <- function(text, envir = parent.frame()) {
with_glue_error(
expr <- parse(text = text, keep.source = FALSE),
"Failed to parse glue component"
)
with_glue_error(
eval(expr, envir),
paste0("Failed to evaluate glue component {", text, "}")
)
}

with_glue_error <- function(expr, message) {
if (!requireNamespace("rlang", quietly = TRUE)) {
return(expr)
}

withCallingHandlers(
expr,
error = function(cnd) {
rlang::abort(
message,
parent = cnd,
call = NULL
)
}
)
}
19 changes: 19 additions & 0 deletions tests/testthat/_snaps/sql.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# get nice errors if rlang installed

Code
glue_sql("{x + }")
Condition
Error:
! Failed to parse glue component
Caused by error in `parse()`:
! <text>:2:0: unexpected end of input
1: x +
^
Code
glue_sql("{NOTFOUND}")
Condition
Error:
! Failed to evaluate glue component {NOTFOUND}
Caused by error:
! object 'NOTFOUND' not found

19 changes: 19 additions & 0 deletions tests/testthat/_snaps/transformer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# get nice errors if rlang installed

Code
identity_transformer("x + ")
Condition
Error:
! Failed to parse glue component
Caused by error in `parse()`:
! <text>:2:0: unexpected end of input
1: x +
^
Code
identity_transformer("NOTFOUND")
Condition
Error:
! Failed to evaluate glue component {NOTFOUND}
Caused by error:
! object 'NOTFOUND' not found

7 changes: 7 additions & 0 deletions tests/testthat/test-sql.R
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,10 @@ describe("glue_sql_collapse", {
)
})
})

test_that("get nice errors if rlang installed", {
expect_snapshot(error = TRUE, {
glue_sql("{x + }")
glue_sql("{NOTFOUND}")
})
})
6 changes: 6 additions & 0 deletions tests/testthat/test-transformer.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
test_that("get nice errors if rlang installed", {
expect_snapshot(error = TRUE, {
identity_transformer("x + ")
identity_transformer("NOTFOUND")
})
})

0 comments on commit db9b656

Please sign in to comment.