Index: waeup/trunk/src/waeup/utils/batching.py
===================================================================
--- waeup/trunk/src/waeup/utils/batching.py	(revision 4876)
+++ waeup/trunk/src/waeup/utils/batching.py	(revision 4877)
@@ -210,4 +210,16 @@
         fd.close()
         return
+
+    def writeFailedRow(self, writer, row, warnings):
+        """Write a row with error messages to error CSV.
+
+        If warnings is a list of strings, they will be concatenated.
+        """
+        error_col = warnings
+        if isinstance(warnings, list):
+            error_col = ' / '.join(warnings)
+        row['--ERRORS--'] = error_col
+        writer.writerow(row)
+        return
     
     def doImport(self, path, headerfields, mode='create', user='Unknown'):
@@ -223,4 +235,5 @@
         failed_headers = [x for x in mapping.values()
                if x != '--IGNORE--']
+        failed_headers.append('--ERRORS--')
         failed_writer = csv.DictWriter(open(failed_path, 'wb'),
                                        failed_headers)
@@ -237,5 +250,6 @@
             if len(conv_warnings):
                 warnings[num] = ', '.join(conv_warnings)
-                failed_writer.writerow(string_row)
+                self.writeFailedRow(failed_writer, string_row, conv_warnings)
+                #failed_writer.writerow(string_row)
                 continue
                 
@@ -243,9 +257,13 @@
                 if not self.parentsExist(row, site):
                     warnings[num] = "Not all parents do exist yet. Skipping"
-                    failed_writer.writerow(string_row)
+                    self.writeFailedRow(
+                        failed_writer, string_row,
+                        "Not all parents do exist yet. Skipping")
                     continue
                 if self.entryExists(row, site):
                     warnings[num] = 'This object already exists. Skipping.'
-                    failed_writer.writerow(string_row)
+                    self.writeFailedRow(
+                        failed_writer, string_row,
+                        "This object already exists. Skipping.")
                     continue
                 obj = self.callFactory()
@@ -256,5 +274,7 @@
                 if not self.entryExists(row, site):
                     warnings[num] = "Cannot remove: no such entry."
-                    failed_writer.writerow(string_row)
+                    self.writeFailedRow(
+                        failed_writer, string_row,
+                        "Cannot remove: no such entry.")
                     continue
                 self.delEntry(row, site)
@@ -263,5 +283,7 @@
                 if obj is None:
                     warnings[num] = "Cannot update: no such entry."
-                    failed_writer.writerow(string_row)
+                    self.writeFailedRow(
+                        failed_writer, string_row,
+                        "Cannot update: no such entry.")
                     continue
                 self.updateEntry(obj, row, site)
Index: waeup/trunk/src/waeup/utils/batching.txt
===================================================================
--- waeup/trunk/src/waeup/utils/batching.txt	(revision 4876)
+++ waeup/trunk/src/waeup/utils/batching.txt	(revision 4877)
@@ -285,12 +285,12 @@
 
 This time a new file was created, which keeps all the rows we could not
-process:
+process and an additional column with error messages:
 
     >>> print open('newcomers.csv.create.pending').read()
-    owner,name,taxpayer,dinoports
-    Barney,Barneys Home,1,2
-    Wilma,Wilmas Asylum,1,1
-    Fred,Freds Dinoburgers,0,10
-    Joey,Joeys Drive-in,0,110
+    owner,name,taxpayer,dinoports,--ERRORS--
+    Barney,Barneys Home,1,2,This object already exists. Skipping.
+    Wilma,Wilmas Asylum,1,1,This object already exists. Skipping.
+    Fred,Freds Dinoburgers,0,10,This object already exists. Skipping.
+    Joey,Joeys Drive-in,0,110,This object already exists. Skipping.
 
 This way we can correct the faulty entries and afterwards retry without
