I often want to parameterize error messages, e.g.
stop(sprintf("function parameter foo = %s, bar = %s", foo, bar))
This works just fine until something like
is.null(foo) arises. Now, the
sprintf output itself is
NULL, and the error condition message becomes pretty worthless. Likewise, perhaps some piece of code was expecting
foo to be a scalar, but instead it happens to be a length > 1 vector ...
glue) return a vector of strings, which
stop() happily accepts and then spits that vector back out. One could write a separate error message for all the possible violations that led one to call
stop in the first place, but that also litters the code when usually they're all just basic variants of the same message: "something about
bar is no good."
Before I set down the path of writing a sane error message replacement/simplification of
sprintf, do others here use some existing (hopefully lightweight) tooling to make creating safe error messages easier? Basically a
paste0 replacement, but with sane defaults that make sense for error messages 99% of the time. Examples of what I'd consider sane defaults:
NULLvalues with "NULL" (handleable with
- replace other length-0 elements with their printed output, e.g.
character(0)with "character(0)" (also handleable with
- replace vectors with some truncated/limited view, e.g.
letters[1:10]with "10 elements (a, b, c, ..., j)"
- replace more complicated objects with perhaps just their class name(s) (and perhaps depth-1
rlang has some class-based approaches for this, which is great for when one needs to design their own classes, but for relatively simple error messages handling mostly base data structures (lists & data frames, atomic vectors, environments, etc.), that approach seems heavyweight, and really I just want a saner string interpolation function(s).