         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))
+      (log-and-fail "Production is not in state \"archived\"")
       ;; 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))
+      (log-and-fail (format "Directory %s already exists" dest-path))
       (fs/exists? tmp-dir)
-      (let [error-msg (format "Directory %s already exists" tmp-dir)]
-        (log/error error-msg)
-        (fail/fail error-msg))
+      (log-and-fail (format "Directory %s already exists" tmp-dir))
       :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 repair
  "Get a production from the archive and prepare it for repairing"
  [{id :id :as production}]

                                 {:as :stream
                                  :basic-auth [(env :archive-web-user) (env :archive-web-password)]})]
        (log/infof "Repairing %s" id)
        (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 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
              (fs/create-dirs tmp-dir)
              (with-open [input (:body response)]
                (io/copy input (fs/file tar-file)))
              ;; extract the tar
              (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))))))))

