Thread (47 messages) flat view 47 messages, 3 authors, 2016-06-15

Re: [PATCH v3 03/19] refs.c: make ref_transaction_commit return an error string

From: Ronnie Sahlberg <hidden>
Date: 2016-06-15 23:00:53

Good points.



On Fri, Apr 25, 2014 at 3:10 PM, Jonathan Nieder [off-list ref] wrote:
Ronnie Sahlberg wrote:
quoted
Let ref_transaction_commit return an optional error string that describes
the transaction failure.  Start by returning the same error as update_ref_lock
returns, modulo the initial error:/fatal: preamble.
s/returns/prints/?
Done, and then was deleted when I reworded the message.
quoted
This will make it easier for callers to craft better error messages when
a transaction call fails.
Interesting.  Can you give an example?  What kind of behavior are we
expecting in callers other than die()-ing or cleaning up and then
die()-ing?
I was thinking a bit too far ahead. You could in theory keep logging multiple
lock failures during the _commit() and then when the transaction fails
and returns
it will have appended a list of all refs that failed and not just the
first ref that failed.

I like this more than having the caller pass in a flag/callback/etc to
decide how noisy to be and whether to gracefully accept errors or exit.
So it seems like an improvement, but may always returning error()
would be better --- more context would help in clarifying this.
quoted
--- a/refs.h
+++ b/refs.h
@@ -268,9 +268,12 @@ void ref_transaction_delete(struct ref_transaction *transaction,
  * Commit all of the changes that have been queued in transaction, as
  * atomically as possible.  Return a nonzero value if there is a
  * problem.  The ref_transaction is freed by this function.
+ * If error is non-NULL it will return an error string that describes
+ * why a commit failed. This string must be free()ed by the caller.
  */
 int ref_transaction_commit(struct ref_transaction *transaction,
-                        const char *msg, enum action_on_err onerr);
+                        const char *msg, char **err,
+                        enum action_on_err onerr);
Is the idea that if I pass in a pointer &err then
ref_transaction_commit will take the action described by onerr *and*
write its error message to err?
Temporarily, yes.
Shortly after this patch I remove the onerr argument completely.
But I want to keep the "pass error back to caller" and "get rid of
onerr" as two separate patches.
I think it is easier to follow the flow of changes if they are done in
two separate steps.
Probably squashing with patch 07 would make this easier to read (and
wouldn't require changing any messages at that point).
See above.
[...]
quoted
--- a/refs.c
+++ b/refs.c
[...]
quoted
@@ -3443,6 +3447,12 @@ int ref_transaction_commit(struct ref_transaction *transaction,
                                             update->flags,
                                             &update->type, onerr);
              if (!update->lock) {
+                     if (err) {
+                             const char *str = "Cannot lock the ref '%s'.";
+                             *err = xmalloc(PATH_MAX + 24);
+                             snprintf(*err, PATH_MAX + 24, str,
+                                      update->refname);
+                     }
Might be clearer to use a helper similar to path.c::mkpathdup

        char *aprintf(const char *fmt, ...)
        {
                char *result;
                struct strbuf sb = STRBUF_INIT;
                va_list args;

                va_start(args, fmt);
                strbuf_vaddf(&sb, fmt, args);
                va_end(args);

                return strbuf_detach(&sb);
        }

or to have the caller pass in a pointer to strbuf instead of char *.
strbuf as argument is probably the right thing to do. I am doing that change.
The rest looks good to me.

Thanks,
Jonathan
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help