From 29addd06b26192f0d3e1761e7e13b291baf7c5a1 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Tue, 22 Sep 2009 08:44:04 +0000
Subject: [PATCH] - Patch #569364 by bjaspan, yched: handle failures on field
 storage creation.

---
 modules/field/field.crud.inc               | 12 ++++++++-
 modules/field/field.test                   | 29 ++++++++++++++++++++++
 modules/simpletest/tests/field_test.module | 10 ++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc
index d837f8aaa241..7f316c4dbac3 100644
--- a/modules/field/field.crud.inc
+++ b/modules/field/field.crud.inc
@@ -291,7 +291,17 @@ function field_create_field($field) {
 
   // Invoke hook_field_storage_create_field after the field is
   // complete (e.g. it has its id).
-  module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_create_field', $field);
+  try {
+    module_invoke(variable_get('field_storage_module', 'field_sql_storage'), 'field_storage_create_field', $field);
+  }
+  catch (Exception $e) {
+    // If storage creation failed, remove the field_config record before
+    // rethrowing the exception.
+    db_delete('field_config')
+      ->condition('id', $field['id'])
+      ->execute();
+    throw $e;
+  }
 
   // Clear caches
   field_cache_clear(TRUE);
diff --git a/modules/field/field.test b/modules/field/field.test
index 9d770076f3a8..b530885add12 100644
--- a/modules/field/field.test
+++ b/modules/field/field.test
@@ -1559,6 +1559,35 @@ class FieldCrudTestCase extends FieldTestCase {
     }
   }
 
+  /**
+   * Test failure to create a field.
+   */
+  function testCreateFieldFail() {
+    $field_name = 'duplicate';
+    $field_definition = array('field_name' => $field_name, 'type' => 'test_field');
+    $query = db_select('field_config')->condition('field_name', $field_name)->countQuery();
+
+    // The field does not appear in field_config.
+    $count = $query->execute()->fetchField();
+    $this->assertEqual($count, 0, 'A field_config row for the field does not exist.');
+
+    // Make field creation fail.
+    variable_set('field_storage_module', 'field_test');
+    
+    // Try to create the field.
+    try {
+      $field = field_create_field($field_definition);
+      $this->assertTrue(FALSE, 'Field creation (correctly) fails.');
+    }
+    catch (Exception $e) {
+      $this->assertTrue(TRUE, 'Field creation (correctly) fails.');
+    }
+
+    // The field does not appear in field_config.
+    $count = $query->execute()->fetchField();
+    $this->assertEqual($count, 0, 'A field_config row for the field does not exist.');
+  }
+    
   /**
    * Test reading back a field definition.
    */
diff --git a/modules/simpletest/tests/field_test.module b/modules/simpletest/tests/field_test.module
index 642d7878e80a..a83d8dff3b1e 100644
--- a/modules/simpletest/tests/field_test.module
+++ b/modules/simpletest/tests/field_test.module
@@ -714,3 +714,13 @@ function field_test_field_delete($obj_type, $object, $field, $instance, $items)
   $args = func_get_args();
   field_test_memorize(__FUNCTION__, $args);
 }
+
+/**
+ *
+ * 'Field storage' API.
+ *
+ */
+
+function field_test_field_storage_create_field($field) {
+  throw new Exception('field_test storage module always fails to create fields');
+}
-- 
GitLab