diff --git a/NEWS.md b/NEWS.md index 902c2565e4..2bf24ce42d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # CHANGES IN knitr VERSION 1.31 +- The `sql` engine now correctly captures error with the chunk option `error = TRUE` (thanks, @colearendt, rstudio/rmarkdown#1208). + - The chunk option `collapse = TRUE` now works as expected when the chunk option `attr.*` or `class.*` is provided. By this change, The chunk option `collapse = TRUE` forces `attr.*` and `class.*` be `NULL` except for the chunk options `attr.source` and `class.source` (thanks, @aosavi @cderv @atusy, #1902 #1906). # CHANGES IN knitr VERSION 1.30 diff --git a/R/engine.R b/R/engine.R index 044e81f314..c66e587d06 100644 --- a/R/engine.R +++ b/R/engine.R @@ -546,18 +546,27 @@ eng_sql = function(options) { query = interpolate_from_env(conn, sql) if (isFALSE(options$eval)) return(engine_output(options, query, '')) - if (is_sql_update_query(query)) { - DBI::dbExecute(conn, query) - data = NULL - } else if (is.null(varname) && max.print > 0) { - # execute query -- when we are printing with an enforced max.print we - # use dbFetch so as to only pull down the required number of records - res = DBI::dbSendQuery(conn, query) - data = DBI::dbFetch(res, n = max.print) - DBI::dbClearResult(res) - } else { - data = DBI::dbGetQuery(conn, query) - } + data = tryCatch({ + if (is_sql_update_query(query)) { + DBI::dbExecute(conn, query) + NULL + } else if (is.null(varname) && max.print > 0) { + # execute query -- when we are printing with an enforced max.print we + # use dbFetch so as to only pull down the required number of records + res = DBI::dbSendQuery(conn, query) + data = DBI::dbFetch(res, n = max.print) + DBI::dbClearResult(res) + data + } else { + DBI::dbGetQuery(conn, query) + } + }, error = function(e) { + if (!options$error) stop(e) + e + }) + + if (inherits(data, "error")) + return(engine_output(options, query, one_string(data))) # create output if needed (we have data and we aren't assigning it to a variable) output = if (length(dim(data)) == 2 && ncol(data) > 0 && is.null(varname)) capture.output({