
Explain an error from rmoriebricklayer (or a package built on it)
Source:R/explain_error.R
explerr.RdFinds where an error or warning message comes from, without a language model and without the network: every message the packages raise is written in their code, so the code is searched. A message built from parts (a file name, a number) matches with those parts as wildcards; one that was cut short or retyped matches by its words. For each match you get the function that raises it, the exported functions it is reached from (their help pages say what they expect), and the message as written, which usually says what to do.
Usage
explerr(msg = geterrmessage(), pkgs = NULL, n = 3L)Arguments
- msg
The message: the text of an error, as R printed it (“Error in f(x) : ...” is fine), a condition object, or a
try()result. Default: the last error of this session (geterrmessage()). Or a data frame of check rows with the columnscheck,okanddetail, asrmbl verify --jsonwrites them andvrfcpsreturns them inchecks: each failed row is explained.- pkgs
Character vector of installed packages to search. The default,
NULL, means this package, or the comma-separated list inRMBL_PACKAGES: an environment variable that a package built on this one sets for its own command line.- n
How many matches to return, best first: a whole number, default 3.
Value
A data frame with at most n rows, best match first, and the
character columns package, raised_by (the function whose code
raises it), exported (the exported functions that reach it,
separated by commas), kind ("error" or "warning"),
message (the message as written, with ... where a value goes)
and match ("exact" or the share of its words found, such as
"80% of its words"). No rows when the message is not one of these
packages' own: it came from another package or from R, and
llmask can help with it. For a data frame of check rows: one
row per failed check, with the columns check, detail,
explanation (what the failure means and what to do) and
raised_by (pkg::fn when the detail is a message of these
packages, else NA).
Details
The first call in a session walks the body of every function in the
searched packages and collects each stop(), warning() and
usage error whose literal text has at least 12 letters. A message built
with sprintf(), gettextf(), paste() or paste0()
becomes a template with its computed parts as wildcards. Each raising
function is traced up to four calls to the exported functions that reach
it (at most six are listed). The table is kept in memory for the session
(about a second to build for this package), and, while a person is
watching an interactive session and the answer cache is on, also saved as
an .rds file in the answer-cache directory.
The answer-cache directory is the one tools::R_user_dir() gives for
"rmoriebricklayer" and "cache", or the one the
rmoriebricklayer.llmcachedir option names when it is set. The cache is
off under options(morie.quiet = TRUE), MORIE_LLM_CACHE=off,
tests and R CMD check.
The message is cleaned first: an “Error in f(x) :” or “Warning message:” prefix is dropped, curly quotes become straight ones and white space is collapsed. A template that matches the start of the message as a regular expression is an exact match and ranks first (longer templates before shorter ones). Otherwise a template scores \(0.6 h / |m| + 0.4 h / |t|\), where \(h\) is the number of shared words (three letters or more, common words left out, at least two needed), \(|m|\) the words of the message and \(|t|\) those of the template; scores of 0.55 and above are kept.
Errors: msg that is not character text, a condition or a data
frame with the columns check, ok and detail;
n not a whole number of 1 or more; pkgs that are not
installed.
Examples
msg <- "`prompt` must be a single non-empty string"
explerr(msg, pkgs = "rmoriebricklayer")
#> package raised_by
#> 1 rmoriebricklayer .rmbl_string1
#> 2 rmoriebricklayer .bl_tmpl_name
#> 3 rmoriebricklayer .rmbl_fips_scheme
#> exported kind
#> 1 llmask, agentbndl, anltab, arccap, arcfind, arcget error
#> 2 blcli, rmblapp, usecpstmpl error
#> 3 blcli, capsule_sign, cpsatst, cpsbndlvrf, cpschkatst, cpssign error
#> message match
#> 1 `...` must be a single non-empty string exact
#> 2 `name` must be a single non-empty string 80% of its words
#> 3 `scheme` must be a single non-empty string 80% of its words
# a condition object
e <- tryCatch(kemsz(3), error = identity)
explerr(e, n = 1)
#> package raised_by exported kind
#> 1 rmoriebricklayer .rmbl_kem_level kemkg, kemsz, kemdecap, kemencap error
#> message match
#> 1 `...` must be one of 512, 768 or 1024 exact
# the failed rows of a capsule check
rows <- data.frame(
check = c("data_present", "data_sha256"),
ok = c(TRUE, FALSE),
detail = c("d.csv", "expected 01..., got 9c...")
)
explerr(rows)$explanation
#> [1] "the data file's bytes differ from the pinned SHA-256: restore the file, or pin the new bytes with cpsrfrsh() (rmbl refresh)"
# n must be at least 1
try(explerr(msg, n = 0))
#> Error : `n` must be a whole number of 1 or more
if (FALSE) { # interactive()
# an error caught with try(), and the message as R prints it, with the call
# in front
r <- try(llmcfg(no.such = 1), silent = TRUE)
explerr(r, pkgs = "rmoriebricklayer")
explerr(
paste0(
"Error in mrkprf(x, 9) : `index` must be between 1 and the number ",
"of chunks"
),
n = 1
)
# a message retyped from memory
explerr("index between number chunks", n = 1)
# R's own messages are not in the table: no rows
nrow(explerr("object 'x' not found"))
}