bibo mao <maob...@loongson.cn> writes: > The question how to use error_propagate() comparing with error_setg() since > there is such API. :)
error_propagate() should be mostly avoided in new code. It still exists because plenty of old code uses it. It can also be used to keep only first of several errors, but that's rarely a good idea. There's usage advice in include/qapi/error.h's big comment. Relevant parts for your convenience: * = Passing errors around = * * Errors get passed to the caller through the conventional @errp * parameter. * * Create a new error and pass it to the caller: * error_setg(errp, "situation normal, all fouled up"); * * Call a function, receive an error from it, and pass it to the caller * - when the function returns a value that indicates failure, say * false: * if (!foo(arg, errp)) { * handle the error... * } * - when it does not, say because it is a void function: * ERRP_GUARD(); * foo(arg, errp); * if (*errp) { * handle the error... * } * More on ERRP_GUARD() below. * * Code predating ERRP_GUARD() still exists, and looks like this: * Error *err = NULL; * foo(arg, &err); * if (err) { * handle the error... * error_propagate(errp, err); // deprecated * } * Avoid in new code. Do *not* "optimize" it to * foo(arg, errp); * if (*errp) { // WRONG! * handle the error... * } * because errp may be NULL without the ERRP_GUARD() guard. * * But when all you do with the error is pass it on, please use * foo(arg, errp); * for readability. [...] * Pass an existing error to the caller: * error_propagate(errp, err); * This is rarely needed. When @err is a local variable, use of * ERRP_GUARD() commonly results in more readable code. * * Pass an existing error to the caller with the message modified: * error_propagate_prepend(errp, err, * "Could not frobnicate '%s': ", name); * This is more concise than * error_propagate(errp, err); // don't do this * error_prepend(errp, "Could not frobnicate '%s': ", name); * and works even when @errp is &error_fatal. * * Receive and accumulate multiple errors (first one wins): * Error *err = NULL, *local_err = NULL; * foo(arg, &err); * bar(arg, &local_err); * error_propagate(&err, local_err); * if (err) { * handle the error... * } * * Do *not* "optimize" this to * Error *err = NULL; * foo(arg, &err); * bar(arg, &err); // WRONG! * if (err) { * handle the error... * } * because this may pass a non-null err to bar(). * * Likewise, do *not* * Error *err = NULL; * if (cond1) { * error_setg(&err, ...); * } * if (cond2) { * error_setg(&err, ...); // WRONG! * } * because this may pass a non-null err to error_setg(). Questions?