diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc index d837f8aaa24..7f316c4dbac 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 9d770076f3a..b530885add1 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 642d7878e80..a83d8dff3b1 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'); +}