Add an API to prefix an already set error with a caller-centric message. If multiple errors are set, all are prefixed individually.
Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com> --- include/qapi/error.h | 6 ++++++ util/error.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/qapi/error.h b/include/qapi/error.h index f44c451..b25c72f 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -78,6 +78,12 @@ ErrorClass error_get_class(const Error *err); Error *error_copy(const Error *err); /** + * Prefix an error message with a formatted string. + */ + +void error_prefix(Error *err, const char *fmt, ...); + +/** * Get a human readable representation of an error object. */ const char *error_get_pretty(Error *err); diff --git a/util/error.c b/util/error.c index 890ce58..e9c23ce 100644 --- a/util/error.c +++ b/util/error.c @@ -19,6 +19,7 @@ struct Error char *msg; ErrorClass err_class; struct Error *next; + bool prefixed; }; Error *error_abort; @@ -142,6 +143,26 @@ const char *error_get_pretty(Error *err) return err->msg; } +void error_prefix(Error *err, const char *fmt, ...) { + char *msg; + char *fmt_full; + va_list ap; + + if (!err || err->prefixed) { + return; + } + err->prefixed = true; + + msg = err->msg; + fmt_full = g_strdup_printf("%s%%s", fmt); + + va_start(ap, fmt); + err->msg = g_strdup_printf(fmt_full, ap, msg); + va_end(ap); + g_free(fmt_full); + g_free(msg); +} + void error_report_err(Error *err) { error_report("%s", error_get_pretty(err)); @@ -170,6 +191,11 @@ void error_propagate(Error **dst_errp, Error *local_err) *dst_errp = local_err; for (i = local_err; i; i = i->next) { + /* Propagation implies that the caller is no longer the owner of the + * error. Therefore reset prefixes, so higher level handlers can + * prefix again. + */ + i->prefixed = false; dst_errp = &i->next; } *dst_errp = old_dst_err; -- 1.9.1