30
30
* job. Since the value of @errp is about handling the error, the
31
31
* function should not examine it.
32
32
*
33
+ * - The function may pass @errp to functions it calls to pass on
34
+ * their errors to its caller. If it dereferences @errp to check
35
+ * for errors, it must use ERRP_GUARD().
36
+ *
33
37
* - On success, the function should not touch *errp. On failure, it
34
38
* should set a new error, e.g. with error_setg(errp, ...), or
35
39
* propagate an existing one, e.g. with error_propagate(errp, ...).
45
49
* = Creating errors =
46
50
*
47
51
* Create an error:
48
- * error_setg(&err, "situation normal, all fouled up");
52
+ * error_setg(errp, "situation normal, all fouled up");
53
+ * where @errp points to the location to receive the error.
49
54
*
50
55
* Create an error and add additional explanation:
51
- * error_setg(&err , "invalid quark");
52
- * error_append_hint(&err , "Valid quarks are up, down, strange, "
56
+ * error_setg(errp , "invalid quark");
57
+ * error_append_hint(errp , "Valid quarks are up, down, strange, "
53
58
* "charm, top, bottom.\n");
59
+ * This may require use of ERRP_GUARD(); more on that below.
54
60
*
55
61
* Do *not* contract this to
56
- * error_setg(&err , "invalid quark\n" // WRONG!
62
+ * error_setg(errp , "invalid quark\n" // WRONG!
57
63
* "Valid quarks are up, down, strange, charm, top, bottom.");
58
64
*
59
65
* = Reporting and destroying errors =
107
113
* Errors get passed to the caller through the conventional @errp
108
114
* parameter.
109
115
*
110
- * Pass an existing error to the caller:
111
- * error_propagate(errp, err);
112
- * where Error **errp is a parameter, by convention the last one.
113
- *
114
- * Pass an existing error to the caller with the message modified:
115
- * error_propagate_prepend(errp, err,
116
- * "Could not frobnicate '%s': ", name);
117
- * This is more concise than
118
- * error_propagate(errp, err); // don't do this
119
- * error_prepend(errp, "Could not frobnicate '%s': ", name);
120
- * and works even when @errp is &error_fatal.
121
- *
122
116
* Create a new error and pass it to the caller:
123
117
* error_setg(errp, "situation normal, all fouled up");
124
118
*
129
123
* handle the error...
130
124
* }
131
125
* - when it does not, say because it is a void function:
126
+ * ERRP_GUARD();
127
+ * foo(arg, errp);
128
+ * if (*errp) {
129
+ * handle the error...
130
+ * }
131
+ * More on ERRP_GUARD() below.
132
+ *
133
+ * Code predating ERRP_GUARD() still exists, and looks like this:
132
134
* Error *err = NULL;
133
135
* foo(arg, &err);
134
136
* if (err) {
135
137
* handle the error...
136
- * error_propagate(errp, err);
138
+ * error_propagate(errp, err); // deprecated
137
139
* }
138
- * Do *not* "optimize" this to
140
+ * Avoid in new code. Do *not* "optimize" it to
139
141
* foo(arg, errp);
140
142
* if (*errp) { // WRONG!
141
143
* handle the error...
142
144
* }
143
- * because errp may be NULL!
145
+ * because errp may be NULL without the ERRP_GUARD() guard.
144
146
*
145
147
* But when all you do with the error is pass it on, please use
146
148
* foo(arg, errp);
160
162
* handle the error...
161
163
* }
162
164
*
165
+ * Pass an existing error to the caller:
166
+ * error_propagate(errp, err);
167
+ * This is rarely needed. When @err is a local variable, use of
168
+ * ERRP_GUARD() commonly results in more readable code.
169
+ *
170
+ * Pass an existing error to the caller with the message modified:
171
+ * error_propagate_prepend(errp, err,
172
+ * "Could not frobnicate '%s': ", name);
173
+ * This is more concise than
174
+ * error_propagate(errp, err); // don't do this
175
+ * error_prepend(errp, "Could not frobnicate '%s': ", name);
176
+ * and works even when @errp is &error_fatal.
177
+ *
163
178
* Receive and accumulate multiple errors (first one wins):
164
179
* Error *err = NULL, *local_err = NULL;
165
180
* foo(arg, &err);
187
202
* error_setg(&err, ...); // WRONG!
188
203
* }
189
204
* because this may pass a non-null err to error_setg().
205
+ *
206
+ * = Why, when and how to use ERRP_GUARD() =
207
+ *
208
+ * Without ERRP_GUARD(), use of the @errp parameter is restricted:
209
+ * - It must not be dereferenced, because it may be null.
210
+ * - It should not be passed to error_prepend() or
211
+ * error_append_hint(), because that doesn't work with &error_fatal.
212
+ * ERRP_GUARD() lifts these restrictions.
213
+ *
214
+ * To use ERRP_GUARD(), add it right at the beginning of the function.
215
+ * @errp can then be used without worrying about the argument being
216
+ * NULL or &error_fatal.
217
+ *
218
+ * Using it when it's not needed is safe, but please avoid cluttering
219
+ * the source with useless code.
220
+ *
221
+ * = Converting to ERRP_GUARD() =
222
+ *
223
+ * To convert a function to use ERRP_GUARD():
224
+ *
225
+ * 0. If the Error ** parameter is not named @errp, rename it to
226
+ * @errp.
227
+ *
228
+ * 1. Add an ERRP_GUARD() invocation, by convention right at the
229
+ * beginning of the function. This makes @errp safe to use.
230
+ *
231
+ * 2. Replace &err by errp, and err by *errp. Delete local variable
232
+ * @err.
233
+ *
234
+ * 3. Delete error_propagate(errp, *errp), replace
235
+ * error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...)
236
+ *
237
+ * 4. Ensure @errp is valid at return: when you destroy *errp, set
238
+ * errp = NULL.
239
+ *
240
+ * Example:
241
+ *
242
+ * bool fn(..., Error **errp)
243
+ * {
244
+ * Error *err = NULL;
245
+ *
246
+ * foo(arg, &err);
247
+ * if (err) {
248
+ * handle the error...
249
+ * error_propagate(errp, err);
250
+ * return false;
251
+ * }
252
+ * ...
253
+ * }
254
+ *
255
+ * becomes
256
+ *
257
+ * bool fn(..., Error **errp)
258
+ * {
259
+ * ERRP_GUARD();
260
+ *
261
+ * foo(arg, errp);
262
+ * if (*errp) {
263
+ * handle the error...
264
+ * return false;
265
+ * }
266
+ * ...
267
+ * }
190
268
*/
191
269
192
270
#ifndef ERROR_H
@@ -287,6 +365,7 @@ void error_setg_win32_internal(Error **errp,
287
365
* the error object.
288
366
* Else, move the error object from @local_err to *@dst_errp.
289
367
* On return, @local_err is invalid.
368
+ * Please use ERRP_GUARD() instead when possible.
290
369
* Please don't error_propagate(&error_fatal, ...), use
291
370
* error_report_err() and exit(), because that's more obvious.
292
371
*/
@@ -298,6 +377,7 @@ void error_propagate(Error **dst_errp, Error *local_err);
298
377
* Behaves like
299
378
* error_prepend(&local_err, fmt, ...);
300
379
* error_propagate(dst_errp, local_err);
380
+ * Please use ERRP_GUARD() and error_prepend() instead when possible.
301
381
*/
302
382
void error_propagate_prepend (Error * * dst_errp , Error * local_err ,
303
383
const char * fmt , ...);
@@ -395,6 +475,46 @@ void error_set_internal(Error **errp,
395
475
ErrorClass err_class , const char * fmt , ...)
396
476
GCC_FMT_ATTR (6 , 7 );
397
477
478
+ /*
479
+ * Make @errp parameter easier to use regardless of argument value
480
+ *
481
+ * This macro is for use right at the beginning of a function that
482
+ * takes an Error **errp parameter to pass errors to its caller. The
483
+ * parameter must be named @errp.
484
+ *
485
+ * It must be used when the function dereferences @errp or passes
486
+ * @errp to error_prepend(), error_vprepend(), or error_append_hint().
487
+ * It is safe to use even when it's not needed, but please avoid
488
+ * cluttering the source with useless code.
489
+ *
490
+ * If @errp is NULL or &error_fatal, rewrite it to point to a local
491
+ * Error variable, which will be automatically propagated to the
492
+ * original @errp on function exit.
493
+ *
494
+ * Note: &error_abort is not rewritten, because that would move the
495
+ * abort from the place where the error is created to the place where
496
+ * it's propagated.
497
+ */
498
+ #define ERRP_GUARD () \
499
+ g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp}; \
500
+ do { \
501
+ if (!errp || errp == &error_fatal) { \
502
+ errp = &_auto_errp_prop.local_err; \
503
+ } \
504
+ } while (0)
505
+
506
+ typedef struct ErrorPropagator {
507
+ Error * local_err ;
508
+ Error * * errp ;
509
+ } ErrorPropagator ;
510
+
511
+ static inline void error_propagator_cleanup (ErrorPropagator * prop )
512
+ {
513
+ error_propagate (prop -> errp , prop -> local_err );
514
+ }
515
+
516
+ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (ErrorPropagator , error_propagator_cleanup );
517
+
398
518
/*
399
519
* Special error destination to abort on error.
400
520
* See error_setg() and error_propagate() for details.
0 commit comments