about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstore/normalise.cc54
1 files changed, 42 insertions, 12 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index a89426cdf22c..cbb0e2f75825 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -153,6 +153,13 @@ public:
 };
 
 
+class SubstError : public Error
+{
+public:
+    SubstError(const format & f) : Error(f) { };
+};
+
+
 
 //////////////////////////////////////////////////////////////////////
 
@@ -209,6 +216,8 @@ void commonChildInit(Pipe & logPipe)
 }
 
 
+/* Convert a string list to an array of char pointers.  Careful: the
+   string list should outlive the array. */
 const char * * strings2CharPtrs(const Strings & ss)
 {
     const char * * arr = new const char * [ss.size() + 1];
@@ -1202,7 +1211,7 @@ private:
     Pid pid;
 
     /* Lock on the store path. */
-    PathLocks outputLock;
+    shared_ptr<PathLocks> outputLock;
     
     typedef void (SubstitutionGoal::*GoalState)();
     GoalState state;
@@ -1310,18 +1319,20 @@ void SubstitutionGoal::tryToRun()
     /* Acquire a lock on the output path. */
     PathSet lockPath;
     lockPath.insert(storePath);
-    outputLock.lockPaths(lockPath);
+    outputLock = shared_ptr<PathLocks>(new PathLocks);
+    outputLock->lockPaths(lockPath);
 
     /* Check again whether the path is invalid. */
     if (isValidPath(storePath)) {
         debug(format("store path `%1%' has become valid") % storePath);
-        outputLock.setDeletion(true);
+        outputLock->setDeletion(true);
         amDone();
         return;
     }
 
-    startNest(nest, lvlInfo,
-        format("substituting path `%1%'") % storePath);
+    printMsg(lvlInfo,
+        format("substituting path `%1%' using substituter `%2%'")
+        % storePath % sub.storeExpr);
     
     /* What's the substitute program? */
     StoreExpr expr = storeExprFromPath(nfSub);
@@ -1396,21 +1407,40 @@ void SubstitutionGoal::finished()
 
     debug(format("substitute for `%1%' finished") % storePath);
 
-    /* Check the exit status. */
-    if (!statusOk(status))
-        throw Error(format("builder for `%1%' %2%")
-            % storePath % statusToString(status));
+    /* Check the exit status and the build result. */
+    try {
+        
+        if (!statusOk(status))
+            throw SubstError(format("builder for `%1%' %2%")
+                % storePath % statusToString(status));
+
+        if (!pathExists(storePath))
+            throw SubstError(
+                format("substitute did not produce path `%1%'")
+                % storePath);
+        
+    } catch (SubstError & e) {
 
-    if (!pathExists(storePath))
-        throw Error(format("substitute did not produce path `%1%'") % storePath);
+        printMsg(lvlInfo,
+            format("substitution of path `%1%' using substituter `%2%' failed: %3%")
+            % storePath % sub.storeExpr % e.msg());
+        
+        /* Try the next substitute. */
+        state = &SubstitutionGoal::tryNext;
+        worker.wakeUp(shared_from_this());
+        return;
+    }
 
     Transaction txn;
     createStoreTransaction(txn);
     registerValidPath(txn, storePath);
     txn.commit();
 
-    outputLock.setDeletion(true);
+    outputLock->setDeletion(true);
     
+    printMsg(lvlChatty,
+        format("substitution of path `%1%' succeeded") % storePath);
+
     amDone();
 }