diff src/c/urweb.c @ 1131:94e83c5533d2

Handling errors during commit
author Adam Chlipala <adamc@hcoop.net>
date Tue, 26 Jan 2010 14:59:19 -0500
parents e1cf925e2074
children b08b73591d2c
line wrap: on
line diff
--- a/src/c/urweb.c	Tue Jan 26 09:04:55 2010 -0500
+++ b/src/c/urweb.c	Tue Jan 26 14:59:19 2010 -0500
@@ -613,6 +613,10 @@
   vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap);
 }
 
+int uw_has_error(uw_context ctx) {
+  return ctx->error_message[0] != 0;
+}
+
 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) {
   cleanup *cl;
 
@@ -2888,21 +2892,61 @@
   return uw_unit_v;
 }
 
+int uw_rollback(uw_context ctx) {
+  int i;
+  cleanup *cl;
+
+  if (ctx->client)
+    release_client(ctx->client);
+
+  for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl)
+    cl->func(cl->arg);
+
+  ctx->cleanup_front = ctx->cleanup;
+
+  for (i = ctx->used_transactionals-1; i >= 0; --i)
+    if (ctx->transactionals[i].rollback != NULL)
+      ctx->transactionals[i].rollback(ctx->transactionals[i].data);
+
+  for (i = ctx->used_transactionals-1; i >= 0; --i)
+    if (ctx->transactionals[i].free)
+      ctx->transactionals[i].free(ctx->transactionals[i].data);
+
+  return ctx->app->db_rollback(ctx);
+}
+
 void uw_commit(uw_context ctx) {
   int i;
 
+  if (uw_has_error(ctx)) {
+    uw_rollback(ctx);
+    return;
+  }
+
   for (i = ctx->used_transactionals-1; i >= 0; --i)
     if (ctx->transactionals[i].rollback != NULL)
-      if (ctx->transactionals[i].commit)
+      if (ctx->transactionals[i].commit) {
         ctx->transactionals[i].commit(ctx->transactionals[i].data);
+        if (uw_has_error(ctx)) {
+          uw_rollback(ctx);
+          return;
+        }
+      }
 
   for (i = ctx->used_transactionals-1; i >= 0; --i)
     if (ctx->transactionals[i].rollback == NULL)
-      if (ctx->transactionals[i].commit)
+      if (ctx->transactionals[i].commit) {
         ctx->transactionals[i].commit(ctx->transactionals[i].data);
-
-  if (ctx->app->db_commit(ctx))
-    uw_error(ctx, FATAL, "Error running SQL COMMIT");
+        if (uw_has_error(ctx)) {
+          uw_rollback(ctx);
+          return;
+        }
+      }
+
+  if (ctx->app->db_commit(ctx)) {
+    uw_set_error_message(ctx, "Error running SQL COMMIT");
+    return;
+  }
 
   for (i = 0; i < ctx->used_deltas; ++i) {
     delta *d = &ctx->deltas[i];
@@ -2954,28 +2998,6 @@
   }
 }
 
-int uw_rollback(uw_context ctx) {
-  int i;
-  cleanup *cl;
-
-  if (ctx->client)
-    release_client(ctx->client);
-
-  for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl)
-    cl->func(cl->arg);
-
-  ctx->cleanup_front = ctx->cleanup;
-
-  for (i = ctx->used_transactionals-1; i >= 0; --i)
-    if (ctx->transactionals[i].rollback != NULL)
-      ctx->transactionals[i].rollback(ctx->transactionals[i].data);
-
-  for (i = ctx->used_transactionals-1; i >= 0; --i)
-    if (ctx->transactionals[i].free)
-      ctx->transactionals[i].free(ctx->transactionals[i].data);
-
-  return ctx->app->db_rollback(ctx);
-}
 
 size_t uw_transactionals_max = SIZE_MAX;