@@ -76,6 +76,21 @@
* But when all you do with the error is pass it on, please use
* foo(arg, errp);
* for readability.
+ *
+ * In a situation where cleanup must happen even if a first step fails,
+ * but the cleanup may also set an error, the first error to occur will
+ * take priority when combined by:
+ * Error *err = NULL;
+ * action1(arg, errp);
+ * action2(arg, &err);
+ * error_propagate(errp, err);
+ * or by:
+ * Error *err = NULL;
+ * action1(arg, &err);
+ * action2(arg, err ? NULL : &err);
+ * error_propagate(errp, err);
+ * although the second form is required if any further error handling
+ * will inspect err to see if all earlier locations succeeded.
*/
#ifndef ERROR_H
The current output of the qapi code generator includes some chained error handling, which looks like: | visit_start_struct(v, (void **)obj, "foo", name, sizeof(FOO), &err); | if (!err) { | if (*obj) { | visit_type_FOO_fields(v, obj, errp); | } | visit_end_struct(v, &err); | } | error_propagate(errp, err); Although there are plans to revisit that code for qemu 2.6, it is still a useful idiom to mention. It is safe because error_propagate() is different than most functions in that you can pass in an already-set errp, and it still does the right thing. Also, describe an alternative form of chained error handling that was proposed during the qapi work, and which may be a bit more obvious to a reader what is happening: | visit_start_implicit_struct(v, (void **)obj, sizeof(FOO), &err); | if (!err) { | visit_type_FOO_fields(v, obj, &err); | visit_end_implicit_struct(v, err ? NULL : &err); | } | error_propagate(errp, err); Signed-off-by: Eric Blake <eblake@redhat.com> --- based on feedback of my qapi series v5 7/46; doc only, so might be worth having in 2.5 --- include/qapi/error.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)