DockerOutput no longer Option[String]
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/Container.scala b/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
index 71872ef..2bd6e0e 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/Container.scala
@@ -78,7 +78,7 @@
      * Gets logs for container.
      */
     def getLogs()(implicit transid: TransactionId): String = {
-        getContainerLogs(containerId) getOrElse ""
+        getContainerLogs(containerId).toOption getOrElse ""
     }
 
     /**
@@ -95,7 +95,7 @@
                 warn(this, s"Retrying to remove container $containerId")
             }
             unpause() // a paused container cannot be removed
-            rmContainer(containerId) match {
+            rmContainer(containerId).toOption match {
                 case None => remove(tryCount - 1)
                 case _    => ()
             }
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala b/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
index bd438c9..f8b3027 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/ContainerPool.scala
@@ -150,7 +150,7 @@
      * Lists ALL containers at this docker point with "docker ps -a --no-trunc".
      * This could include containers not in this pool at all.
      */
-    def listAll()(implicit transid: TransactionId): Array[ContainerState] = listContainers(true)
+    def listAll()(implicit transid: TransactionId): Seq[ContainerState] = listContainers(true)
 
     /**
      * Retrieves (possibly create) a container based on the subject and versioned action.
@@ -422,7 +422,7 @@
      *   2. Periodically re-populates the container pool with fresh (un-instantiated) nodejs containers.
      *   3. Periodically tears down containers that have logically been removed from the system
      */
-    private def nannyThread(allContainers: Array[ContainerState]) = new Thread {
+    private def nannyThread(allContainers: Seq[ContainerState]) = new Thread {
         override def run {
             implicit val tid = TransactionId.invokerWarmup
             if (!standalone) killStragglers(allContainers)
@@ -695,7 +695,7 @@
      * This is needed for startup and shutdown.
      * Concurrent access from clients must be prevented.
      */
-    private def killStragglers(allContainers: Array[ContainerState])(implicit transid: TransactionId) = {
+    private def killStragglers(allContainers: Seq[ContainerState])(implicit transid: TransactionId) = {
         val candidates = allContainers.filter { case ContainerState(id, image, name) => name.startsWith(actionContainerPrefix) }
         info(this, s"Now removing ${candidates.length} leftover containers")
         candidates foreach {
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala b/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
index b975676..d8aa0e7 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/ContainerUtils.scala
@@ -21,6 +21,7 @@
 import whisk.common.TransactionId
 import whisk.core.entity.ActionLimits
 import java.io.File
+import java.io.FileNotFoundException
 import scala.util.Try
 import scala.language.postfixOps
 import whisk.common.LoggingMarkers
@@ -75,17 +76,17 @@
         val containerNetwork = Array("--net", network)
         val cmd = Array("run") ++ makeEnvVars(env) ++ consulServiceIgnore ++ nameOption ++ cpuArg ++ memoryArg ++
             capabilityArg ++ fileHandleLimit ++ processLimit ++ securityOpts ++ containerNetwork ++ Array("-d", image) ++ args
-        runDockerCmd(cmd: _*)
+        runDockerCmd(cmd: _*).toOption
     }
 
     def killContainer(name: String)(implicit transid: TransactionId): DockerOutput = killContainer(Some(name))
 
     def killContainer(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
-        container flatMap { name => runDockerCmd("kill", name) }
+        container.fold(DockerOutput.unavailable)(name => runDockerCmd("kill", name))
     }
 
     def getContainerLogs(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
-        container flatMap { name => runDockerCmd("logs", name) }
+        container.fold(DockerOutput.unavailable)(name => runDockerCmd("logs", name))
     }
 
     def pauseContainer(name: String)(implicit transid: TransactionId): DockerOutput = {
@@ -102,19 +103,19 @@
      * Forcefully removes a container, can be used on a running container but not a paused one.
      */
     def rmContainer(container: ContainerName)(implicit transid: TransactionId): DockerOutput = {
-        container flatMap { name => runDockerCmd("rm", "-f", name) }
+        container.fold(DockerOutput.unavailable)(name => runDockerCmd("rm", "-f", name))
     }
 
     /*
      * List containers (-a if all).
      */
-    def listContainers(all: Boolean)(implicit transid: TransactionId): Array[ContainerState] = {
+    def listContainers(all: Boolean)(implicit transid: TransactionId): Seq[ContainerState] = {
         val tmp = Array("ps", "--no-trunc")
         val cmd = if (all) tmp :+ "-a" else tmp
-        runDockerCmd(cmd: _*) map { output =>
-            val lines = output.split("\n").drop(1) // skip the header
+        runDockerCmd(cmd: _*).toOption map { output =>
+            val lines = output.split("\n").drop(1).toSeq // skip the header
             lines.map(parsePsOutput)
-        } getOrElse Array()
+        } getOrElse Seq()
     }
 
     def getDockerLogSize(containerId: String, mounted: Boolean)(implicit transid: TransactionId): Long = {
@@ -158,10 +159,8 @@
     def getContainerHostAndPort(container: ContainerName)(implicit transid: TransactionId): Option[ContainerAddr] = {
         for (
             name <- container;
-            output <- runDockerCmd("inspect", "--format", "'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'", name)
-        ) yield {
-            ContainerAddr(output.substring(1, output.length - 1), 8080)
-        }
+            output <- runDockerCmd("inspect", "--format", "'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'", name).toOption
+        ) yield ContainerAddr(output.substring(1, output.length - 1), 8080)
     }
 
     def runDockerCmd(args: String*)(implicit transid: TransactionId): DockerOutput = runDockerCmd(false, args)
@@ -201,35 +200,43 @@
      */
     def runDockerCmd(dockerhost: String, skipLogError: Boolean, args: Seq[String])(implicit transid: TransactionId): DockerOutput = {
         val start = transid.started(this, LoggingMarkers.INVOKER_DOCKER_CMD(args(0)))
-        getDockerCmd(dockerhost) map { _ ++ args } map {
-            SimpleExec.syncRunCmd(_)(transid)
-        } map {
-            case (stdout, stderr, exitCode) =>
-                if (exitCode == 0) {
-                    transid.finished(this, start)
-                    Some(stdout.trim)
+
+        try {
+            val fullCmd = getDockerCmd(dockerhost) ++ args
+
+            val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(fullCmd)
+
+            if (exitCode == 0) {
+                transid.finished(this, start)
+                DockerOutput(stdout.trim)
+            } else {
+                if (!skipLogError) {
+                    transid.failed(this, start, s"stdout:\n$stdout\nstderr:\n$stderr", ErrorLevel)
                 } else {
-                    if (!skipLogError) {
-                        transid.failed(this, start, s"stdout:\n$stdout\nstderr:\n$stderr", ErrorLevel)
-                    } else {
-                        transid.failed(this, start)
-                    }
-                    None
+                    transid.failed(this, start)
                 }
-        } getOrElse {
-            transid.failed(this, start, "docker executable not found", ErrorLevel)
-            None
+                DockerOutput.unavailable
+            }
+        } catch {
+            case t: Throwable =>
+                transid.failed(this, start, "error: " + t.getMessage, ErrorLevel)
+                DockerOutput.unavailable
         }
     }
 
-    private def file(path: String) = Try { new File(path) } filter { _.exists } toOption
+    private def getDockerCmd(dockerhost: String): Seq[String] = {
+        def file(path: String) = Try { new File(path) } filter { _.exists } toOption
 
-    def getDockerCmd(dockerhost: String) = {
         val dockerLoc = file("/usr/bin/docker") orElse file("/usr/local/bin/docker")
+
+        val dockerBin = dockerLoc.map(_.toString).getOrElse {
+            throw new FileNotFoundException("Couldn't locate docker binary.")
+        }
+
         if (dockerhost == "localhost") {
-            dockerLoc map { f => Array(f.toString) }
+            Seq(dockerBin)
         } else {
-            dockerLoc map { f => Array(f.toString, "--host", s"tcp://$dockerhost") }
+            Seq(dockerBin, "--host", s"tcp://$dockerhost")
         }
     }
 
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala b/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
index eaf5a8e..4f8069a 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/WhiskContainer.scala
@@ -112,7 +112,7 @@
      * Tear down the container and retrieve the logs.
      */
     def teardown()(implicit transid: TransactionId): String = {
-        getContainerLogs(Some(containerName)).getOrElse("none")
+        getContainerLogs(Some(containerName)).toOption.getOrElse("none")
     }
 
     /**
diff --git a/core/dispatcher/src/main/scala/whisk/core/container/package.scala b/core/dispatcher/src/main/scala/whisk/core/container/package.scala
index 4161c00..9756a85 100644
--- a/core/dispatcher/src/main/scala/whisk/core/container/package.scala
+++ b/core/dispatcher/src/main/scala/whisk/core/container/package.scala
@@ -87,5 +87,9 @@
 
     type ContainerId = Option[String]
 
-    type DockerOutput = Option[String]
+    final class DockerOutput(val toOption: Option[String]) extends AnyVal
+    object DockerOutput {
+        def apply(content: String) = new DockerOutput(Some(content))
+        def unavailable = new DockerOutput(None)
+    }
 }