Reputation: 8194
I would like to build an html document using Rmarkdown in which error messages from R can be displayed as they do natively appear in an R interactive session.
This question is similar, but doesn't have the requirement that error messages appear exactly as in an interactive session: I tried using error=TRUE
for a given chunk, at the error gets prefixed with Error in eval(expr, envir, enclos):
:
With the following chunk:
```{r, error=TRUE}
notexistingvariable
```
I expect:
Error: object 'notexistingvariable' not found
I get:
Error in eval(expr, envir, enclos): object 'notexistingvariable' not found
I tried adding the results="asis"
option, but this has no effect here. I think this only applies to non-error output.
wrap.error
As suggested in the answers, I tried to set a custom wrap.error
function.
test.Rmd
:
---
title: "test"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
wrap.error <- function(x, options) {
# x is an error object, with components "call" and "message". Ignore
# the call, but wrap the result like code:
paste0("```\n## Error: ", x$message, "\n```")
}
```
```{r, error=TRUE}
notexistingvariable
```
Conversion to html:
$ R -e "rmarkdown::render('test.Rmd',output_file='test.html')"
R version 3.5.1 (2018-07-02) -- "Feather Spray"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> rmarkdown::render('test.Rmd',output_file='test.html')
processing file: test.Rmd
|................ | 25%
ordinary text without R code
|................................ | 50%
label: setup (with options)
List of 1
$ include: logi FALSE
|................................................. | 75%
ordinary text without R code
|.................................................................| 100%
label: unnamed-chunk-1 (with options)
List of 1
$ error: logi TRUE
output file: test.knit.md
/usr/bin/pandoc +RTS -K512m -RTS test.utf8.md --to html4 --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output test.html --smart --email-obfuscation none --self-contained --standalone --section-divs --template /home/bli/R/x86_64-pc-linux-gnu-library/3.5/rmarkdown/rmd/h/default.html --no-highlight --variable highlightjs=1 --variable 'theme:bootstrap' --include-in-header /tmp/RtmpAoBtc7/rmarkdown-str53186fa5c04d.html --mathjax --variable 'mathjax-url:https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
Output created: test.html
>
>
The test.html
file looks as follows:
Using wrap.simpleError
, as the updated answer now proposes, works.
Upvotes: 1
Views: 756
Reputation: 44977
(Updated to reflect R 3.5.x changes)
You can set custom renderers for the output (see vignette("knit_print")
), but I think they are not called when an error occurs. The generic wrap()
function is called in that case. knitr
defines a wrap.error()
method, and prior to R 3.5.0, that could be overridden by a user. However, in the latest release of R, methods defined in a package are chosen in preference to those defined by the user, so it no longer works.
However, there is still a solution for some errors. For the example in the question, the error object that is created has class c("simpleError", "error", "condition")
, and knitr
doesn't define a wrap.simpleError()
method. You can define one, and override its handling.
You do it like this:
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
wrap.simpleError <- function(x, options) {
# x is an error object, with components "call" and "message". Ignore
# the call, but wrap the result like code:
paste0("```\n## Error: ", x$message, "\n```")
}
```
```{r, error=TRUE}
notexistingvariable
```
This displays the result like this:
There's also an output hook to handle errors: see https://yihui.name/knitr/hooks/. However, it seems to be called after wrap.error
, when the message is already formed. You could edit that message to delete
the parts you don't want using code like this:
```{r}
knitr::knit_hooks$set(error = function(x, options) {
paste0("```\n",
sub(" in eval(expr, envir, enclos)", "", x, fixed = TRUE),
"\n```")
})
```e
This may be more robust than the wrap.simpleError
approach, which
would stop working if knitr
ever defined a wrap.simpleError
method like that. It will also handle all errors, not just "simpleError"
ones. It has the
disadvantage that it is probably harder to customize it to handle different types of errors, and might not work in different locales where "Error in" is translated to some other language.
Upvotes: 4