                                  {:as :stream
                                   :basic-auth [(env :archive-web-user) (env :archive-web-password)]})]
         (log/infof "Repairing %s" id)
-        (if (client/success? response)
+        (if-not (client/success? response)
+          (do
+            (.close (:body response)) ;; close the stream
+            (log-and-fail (format "Couldn't get %s from archive (%s)" id url)))
           (let [dam-number (prod/dam-number production)
                 tar-file (fs/path tmp-dir (str dam-number ".tar"))]
-            (fail/try*
-              ;; fail fast if any of the filesystem operations below fail
-              ;; create all dirs for this production
-              (log/info "Create dirs" id)
+
+            ;; fail fast if any of the filesystem operations fail. If
+            ;; the filesystem operations silently ignore failures we
+            ;; check the results.
+            (try
+              ;;create all dirs for this production
               (prod/create-dirs production)
               ;; copy tar to tmpdir
-              (log/infof "Copy tar to tmpdir" tmp-dir)
               (fs/create-dirs tmp-dir)
               (with-open [input (:body response)]
                 (io/copy input (fs/file tar-file)))
               ;; extract the tar
-              (log/infof "extract tar %s to %s" tar-file tmp-dir)
-              (shell/sh "tar" "--extract" (str "--file=" tar-file) :dir (fs/file tmp-dir))
-              ;; extract the relevant parts to the structured-path
-              (let [src-path (fs/file tmp-dir dam-number "produkt" dam-number)]
-                (log/infof "extract the relevant parts to the structured-path %s" src-path)
-                (doseq [f (filter #(.isFile %) (file-seq src-path))]
-                  (fs/move f (io/file dest-path (fs/file-name f)))))
-              ;; clear the temporary files
-              (log/info "clear the temporary files")
-              (fs/delete-tree tmp-dir)
-              ;; create the obi config file
-              (log/info "create the obi config file")
-              (obi/config-file production)
-              ;; set the state
-              (log/info "set the state")
-              (prod/set-state! production "structured")))
-          (let [error-msg (format "Couldn't get %s from archive (%s)" id url)]
-            ;; close the stream
-            (.close (:body response))
-            (log/error error-msg)
-            (fail/fail error-msg)))))))
+              (let [{exit :exit} (shell/sh "tar" "--extract" (format "--file=%s" tar-file) :dir (fs/file tmp-dir))]
+                (if-not (= exit 0)
+                  (do
+                    ;; re-set the state back to archived
+                    (prod/set-state! production "archived")
+                    (log-and-fail (format "Failed to extract the tar file %s inside %s" tar-file tmp-dir)))
+                  (do
+                    ;; extract the relevant parts to the structured-path
+                    (let [src-path (fs/file tmp-dir dam-number "produkt" dam-number)]
+                      (doseq [f (filter #(.isFile %) (file-seq src-path))]
+                        (fs/move f (io/file dest-path (fs/file-name f)))))
+                    ;; clear the temporary files
+                    (if-not (fs/delete-tree tmp-dir)
+                      ;; we probably do not need to roll back the state just because we couldn't
+                      ;; clean up some temporary files
+                      (log-and-fail (format "Failed to remove temporary files in %s" tmp-dir))
+                      (do
+                        ;; create the obi config file
+                        (obi/config-file production)
+                        ;; set the state
+                        (prod/set-state! production "structured"))))))
+              (catch Exception e
+                ;; re-set the state back to archived
+                (prod/set-state! production "archived")
+                e))))))))
 

        tmp-dir (fs/path (fs/parent dest-path) (str id "_repair"))]
    (cond
      (not= (:state production) "archived")
      (let [error-msg "Production is not in state \"archived\""]
        (log/error error-msg)
        (fail/fail error-msg))
      ;; checking for the state is not enough: there is a race
      ;; condition as the state is only set after all the files have
      ;; been copied. This takes time. So we also check for the
      ;; existence of some important directories
      (fs/exists? dest-path)
      (let [error-msg (format "Directory %s already exists" dest-path)]
        (log/error error-msg)
        (fail/fail error-msg))
      (fs/exists? tmp-dir)
      (let [error-msg (format "Directory %s already exists" tmp-dir)]
        (log/error error-msg)
        (fail/fail error-msg))
      :else
      (let [production (prod/set-state! production "repairing")
            container-id (container-id production)

              :dist-master (:library_signature production))]
     (-> {:id id} db/production-id-to-archive-id :id))))

(defn- log-and-fail
  "Log an error with given `msg` and return a (Failjure) failure"
  [msg]
  (log/error msg)
  (fail/fail msg))

(defn repair
  "Get a production from the archive and prepare it for repairing"
  [{id :id :as production}]
