Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Add error support code #199
Conversation
vosst
reviewed
Dec 1, 2016
Code is looking good overall. I left a couple of comments inline, mostly nits.
| + * This function calls die() in case of memory allocation failure. | ||
| + **/ | ||
| +__attribute__ ((format(printf, 3, 4))) | ||
| +struct sc_error *sc_error_init(const char *domain, int code, const char *msgfmt, |
chipaca
Dec 2, 2016
Member
also, consider attributes nonnull (unlless format wanrs about a null msgfmt already), warn_unused_result, returns_nonnull.
| +/** | ||
| + * Get the error domain out of an error object. | ||
| + * | ||
| + * The error domain acts as a namespace for error codes. The return value must |
vosst
Dec 1, 2016
Contributor
nit: I would propose to rephrase the doc string a little bit: "No change of ownership takes place".
zyga
Dec 2, 2016
Collaborator
Hmm, this feels C++-ish but as long as we're consistent that's okay. Changed
| +/** | ||
| + * Get the error message out of an error object. | ||
| + * | ||
| + * The error message is bound to the life-cycle of the error object. |
| + * The error message is derived from the data in the error, using the special | ||
| + * errno domain to provide additional information if that is available. | ||
| + **/ | ||
| +void sc_error_die(struct sc_error *error); |
zyga
Dec 2, 2016
Collaborator
I called this sc_die_on_error to make it dead obvious the cost of the naming scheme.
| + * the caller did not provide a location for the error to be stored then the | ||
| + * sc_error_die() is called as a safety measure. | ||
| + **/ | ||
| +void sc_error_forward(struct sc_error **recepient, struct sc_error *error); |
vosst
Dec 1, 2016
Contributor
I'm slightly confused by this method (likely because I lack a bit of context): I would have expected sc_error* sc_error_forward_or_die(struct sc_error* error);, with the function dying if error is NULL.
zyga
Dec 1, 2016
Collaborator
This is essentially a way to enforce a contract that an error is forwarded to the caller or we die right here, right now. For usage context look at https://github.com/snapcore/snap-confine/blob/arguments/src/snap-confine-args.c#L135
|
Thanks for the review. I'll fix something in another branch and return to this quickly. |
chipaca
reviewed
Dec 2, 2016
It looks good. I've pointed out some attributes you could use to helper the compiler errors/warnings, but those are pico-nits.
One thing that does bother me a little is that you pay for formatting things up front instead of at die time. Had you considered carrying around the msgfmt and va_list and doing the vasprintf at the end if needed?
| + * This function calls die() in case of memory allocation failure. | ||
| + **/ | ||
| +__attribute__ ((format(printf, 3, 4))) | ||
| +struct sc_error *sc_error_init(const char *domain, int code, const char *msgfmt, |
chipaca
Dec 2, 2016
Member
also, consider attributes nonnull (unlless format wanrs about a null msgfmt already), warn_unused_result, returns_nonnull.
| + * | ||
| + * This function calls die() in case of memory allocation failure. | ||
| + **/ | ||
| +__attribute__ ((format(printf, 2, 3))) |
| + * The error domain acts as a namespace for error codes. The return value must | ||
| + * not be released in any way. | ||
| + **/ | ||
| +const char *sc_error_domain(struct sc_error *err); |
| + * The error message is derived from the data in the error, using the special | ||
| + * errno domain to provide additional information if that is available. | ||
| + **/ | ||
| +void sc_error_die(struct sc_error *error); |
zyga
Dec 2, 2016
Collaborator
I called this sc_die_on_error to make it dead obvious the cost of the naming scheme.
| + * the caller did not provide a location for the error to be stored then the | ||
| + * sc_error_die() is called as a safety measure. | ||
| + **/ | ||
| +void sc_error_forward(struct sc_error **recepient, struct sc_error *error); |
vosst
Dec 1, 2016
Contributor
I'm slightly confused by this method (likely because I lack a bit of context): I would have expected sc_error* sc_error_forward_or_die(struct sc_error* error);, with the function dying if error is NULL.
zyga
Dec 1, 2016
Collaborator
This is essentially a way to enforce a contract that an error is forwarded to the caller or we die right here, right now. For usage context look at https://github.com/snapcore/snap-confine/blob/arguments/src/snap-confine-args.c#L135
|
@chipaca In C that's generally hard as va_list is hard to "store" for longer than a function call and even if you could then there's no guarantee that value stored there are still sane (e.g. pointers). One of the non-perks of manual memory management :/ |
zyga
added some commits
Dec 2, 2016
|
LGTM. |
zyga
merged commit 9227986
into
master
Dec 5, 2016
1 check passed
zyga
deleted the
errors
branch
Dec 5, 2016
|
I took a quick look at this PR and it looks ok to me. |
zyga commentedDec 1, 2016
This patch adds die()-like APIs that can carry error information around
the control flow. They are meant to provide richer error information in
cases where the error is not fatal and needs to be returned to the
caller. The APIs are 100% tested and also integrate with die() where
appropriate().
Signed-off-by: Zygmunt Krynicki zygmunt.krynicki@canonical.com