Error Messages
I am an anxious person. So error messages always makes my heart beat faster. Hopefully, following the Pareto Principle, 80% of error messages are mild while 20% are the really tough one. The point is to solve the first kind as quickly as possible and effortless. To do so, allow the user to solve the issue by himself with clear messages and hints (in the case of errors related to input files or parameters). Clear presentation of the context and precise localization of the error in the code will save a lot of useless and tedious work to the developer. The time spared on the easy errors just by having better messages, then can be reallocated to the second kind of errors, the troublemakers.
An unknown error has occurred.
The Ultimate Useless Error Message Ever!
After spending a lot of time redesigning my R package error messages, I have developed good practices for writing helpful console error messages in a standardized way using CLI libraries.
Writing Error Messages
Problem Statement
- Explain exactly what went wrong.
- â Warning: the program continue running but something might be wrong.
- â Alert: The program stopped because they are a critical problem that must be fixed.
- Only use one of these two verbs:
must
: the problem is clearly identified.can not
: do not know the problem.
- Do not blame the user. Describe the problem and provide context.
Error Location
- Indicate where in the code or system an error occurs.
- File name and line number.
- Module and function.
- The đ Stack trace is the list of calls leading up to the error. The last call indicate the exact error location.
It prevents you to search for hours where the bug occurs in your code.
Error Hint
- âšī¸ Hint: an info bullet to suggest a solution to the user.
- One bullet = one hint.
Example:
â Your name
Claude63
must contain only letters.âšī¸ Check your name does not include numbers.
Punctuation
- Complete sentence.
- Singular form.
- A sentence must end with a period.
Where to Write Error Messages in Code
For simple program
For a simple script, the simplest is just to write the error message directly where it happens.
inversion <- function(number) {
if (number != 0) {
return(1 / number)
} else {
cat("ERROR: Number must be different than zero.")
cat("INFO: Check that the value of 'number' is different from zero.")
stop()
}
}
For complex program
In complex program such as an R package (I keep this example but the same logic applies for C, java, python, etc.) writing error messages directly in the code is not good.
- The more complex the program, the harder it becomes to modify error messages and keep them consistent over version and functions.
- Error messages are often redundants. Even if your code itself is not repetitive, your messages may be repeated in multiple places. It is harder to stay consistent because you must replicate by hand the same error message over and over in different context.
- Lengthy error messages in the middle of your code make it harder to read and review.
The solution is to make a dictionnary of error messages. In a dedicated file, for instance error_messages.R
, write the complete list of error messages and their associated keys. Then in your code, call the needed error message by its key.
R/
âââ error_messages.R
âââ main.R
error_messages.R
error_messages$err001 = c(
"ERROR: Number must be different than zero.",
"INFO: Check that the value of 'number' is different from zero."
)
error_messages$err002 = ...
main.R
inversion <- function(number) {
if (number != 0) {
return(1 / number)
} else {
error_messages$err001
}
}
This way you code is shorter, cleaner and you can change all the error messages in a centralized way.
Command Line Interfaces
Last but not least, you need to use a dedicated Command Line Interfaces (CLI) for error messages. Still with the example of R, the package cli
provide the tools to build structured messages.
- Error and warning messages formatting
- Generate stack track
- Text formatting
- Handle variables
- Word pluralizing
The following command display a default format for Success, alert, warning, hint type messages. It also automatically generate the stack track to localize the where the error occurs.
cli_alert_success("Success.")
cli_alert_danger("Alert.")
cli_alert_warning("Warning.")
cli_alert_info("Hint.")
Text formatting
cli_h1("Heading 1")
cli_h2("Heading 2")
cli_li("Item 1")
cli_li("Item 2")
Using variable
fruits <- c("banana", "orange", "strawberry")
cli_alert_success("Recorded {length(user_names)} fruits.")
Pluralize words
n_files = 3
n_dirs = 1
cli_alert_info("Found {n_files} file{?s} and {n_dirs} director{?y/ies}.")
Dictionnary of error messages combined with cli
R/
âââ error_messages.R
âââ main.R
error_messages.R
error_messages$err001 =
c(
"x" = "{.field number} must be different from zero.",
"i" = "The value of {.field number} is {.val {number}}.",
">" = "Check {.field number} is not zero."
)
error_messages$err002 = ...
main.R
inversion <- function(number) {
if (number != 0) {
return(1 / number)
} else {
cli_abort(error_messages$err001)
}
}
CLI Libraries in Other Languages
- Python: Click
- C++: fmt
- Php: Symfony CLI
- Java: Picocli
Conclusion
- Use short and consistent in style and format error messages.
- Trace back and description of context is mandatory.
- Use a dictionnary of error messages to centralize them and lighten your code.
- Use CLI libraries to help you write formatted and standardized error messages.
References
- R package
cli
: r-lib/cli - Documentation: R package cli doc
Relevant Tags
About the Author
Latest Articles
-
Chado: the GMOD Database Schema
the Generic Model Organism Database project or GMOD is a collection of open source software tools for managing, visualising, storing, and disseminating genetic and genomic data.JAN 2025 ¡ PIERRE-EDOUARD GUERIN -
Error Messages
I am an anxious person. So error messages always makes my heart beat faster. Hopefully, following the Pareto Principle, 80% of error messages are mild while 20% are the really tough one. The point is to solve the first kind as quickly as possible and effortless. To do so, allow the user to solve the issue by himself with clear messages and hints (in the case of errors related to input files or parameters). Clear presentation of the context and precise localization of the error in the code will save a lot of useless and tedious work to the developer. The time spared on the easy errors just by having better messages, then can be reallocated to the second kind of errors, the troublemakers.NOV 2024 ¡ PIERRE-EDOUARD GUERIN -
Generative AI
I was fortunate to follow the course of Sven Warris about software tools to integrate genAI into your own work and applications. The course is aimed at data scientists and bioinformaticians.MAY 2024 ¡ PIERRE-EDOUARD GUERIN