diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+# 1.6.7
+
+* flush stdout when using `echo`, not just `echo_n`
+* fix should be able to silence stderr when using `runHandle`
+* expose RunFailed
+
 # 1.6.6
 
 * add prependToPath function
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -97,6 +97,7 @@
 Of course, the development machine may need to be exactly the same OS as the server.
 
 I recommend using the boilerplate at the top of this example in your projects.
+This includes setting line buffering if you are dealing with text and not binary data.
 
 ~~~~~ {.haskell}
     {-# LANGUAGE OverloadedStrings #-}
@@ -106,16 +107,18 @@
     import Data.Text as T
     default (T.Text)
 
-    main = shelly $ verbosely $ do
-      host <- run "uname" ["-n"]
-      if T.stripEnd host === "local-machine"
-        then do d <- cmd "date"
-                c <- escaping False $ cmd "git" "log -1 | head -1 | awk '{print $2}'"
-                appendfile "log/deploy.log" $ T.intercalate " - " [T.stripEnd d, c]
-                uploads "my-server:/remote/path/" ["deploy"]
-                sshPairs_ "my-server" [("cd", ["/remote/path"]), ("./deploy", [])]
-        else do
-              cmd "./script/angel"
+    main =  do
+      hSetBuffering stdout LineBuffering
+      shelly $ verbosely $ do
+        host <- run "uname" ["-n"]
+        if T.stripEnd host === "local-machine"
+          then do d <- cmd "date"
+                  c <- escaping False $ cmd "git" "log -1 | head -1 | awk '{print $2}'"
+                  appendfile "log/deploy.log" $ T.intercalate " - " [T.stripEnd d, c]
+                  uploads "my-server:/remote/path/" ["deploy"]
+                  sshPairs_ "my-server" [("cd", ["/remote/path"]), ("./deploy", [])]
+          else do
+                cmd "./script/angel"
 
     -- same path on remote host
     -- will create directories
diff --git a/shelly.cabal b/shelly.cabal
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -1,6 +1,6 @@
 Name:       shelly
 
-Version:     1.6.6
+Version:     1.6.7
 Synopsis:    shell-like (systems) programming in Haskell
 
 Description: Shelly provides convenient systems programming in Haskell,
@@ -48,7 +48,7 @@
 
   Build-depends:
     containers                >= 0.4.2.0,
-    time                      >= 1.3 && < 1.6,
+    time                      >= 1.3 && < 1.7,
     directory                 >= 1.1.0.0 && < 1.3.0.0,
     mtl                       >= 2,
     process                   >= 1.0,
diff --git a/src/Shelly.hs b/src/Shelly.hs
--- a/src/Shelly.hs
+++ b/src/Shelly.hs
@@ -73,6 +73,7 @@
          -- * Exceptions
          , bracket_sh, catchany, catch_sh, handle_sh, handleany_sh, finally_sh, ShellyHandler(..), catches_sh, catchany_sh
          , ReThrownException(..)
+         , RunFailed(..)
 
          -- * convert between Text and FilePath
          , toTextIgnore, toTextWarn, FP.fromText
@@ -1143,10 +1144,10 @@
     runWithColor_ =
         runHandles exe args [OutHandle Inherit] $ \inH _ errH -> do
           state <- get
-          errVar <- liftIO $ do
+          errs <- liftIO $ do
             hClose inH -- setStdin was taken care of before the process even ran
-            (putHandleIntoMVar mempty (|>) errH (sPutStderr state) (sPrintStderr state))
-          errs <- liftIO $ lineSeqToText `fmap` wait errVar
+            errVar <- (putHandleIntoMVar mempty (|>) errH (sPutStderr state) (sPrintStderr state))
+            lineSeqToText `fmap` wait errVar
           modify $ \state' -> state' { sStderr = errs }
           return ()
 
@@ -1160,11 +1161,11 @@
           -> (Handle -> Sh a) -- ^ stdout handle
           -> Sh a
 runHandle exe args withHandle = runHandles exe args [] $ \_ outH errH -> do
-    putStderr <- gets sPutStderr
-    errPromise <- liftIO $ async $ transferLinesAndCombine errH putStderr
+    state <- get
+    errVar <- liftIO $
+      (putHandleIntoMVar mempty (|>) errH (sPutStderr state) (sPrintStderr state))
     res <- withHandle outH
-    errs <- liftIO $ wait errPromise
-
+    errs <- liftIO $ lineSeqToText `fmap` wait errVar
     modify $ \state' -> state' { sStderr = errs }
     return res
 
diff --git a/src/Shelly/Base.hs b/src/Shelly/Base.hs
--- a/src/Shelly/Base.hs
+++ b/src/Shelly/Base.hs
@@ -105,7 +105,7 @@
 runSh = runReaderT . unSh
 
 data ReadOnlyState = ReadOnlyState { rosFailToDir :: Bool }
-data State = State 
+data State = State
    { sCode :: Int -- ^ exit code for command that ran
    , sStdin :: Maybe Text -- ^ stdin for the command to be run
    , sStderr :: Text -- ^ stderr for command that ran
@@ -256,12 +256,12 @@
 
 get :: Sh State
 get = do
-  stateVar <- ask 
+  stateVar <- ask
   liftIO (readIORef stateVar)
 
 modify :: (State -> State) -> Sh ()
 modify f = do
-  state <- ask 
+  state <- ask
   liftIO (modifyIORef state f)
 
 -- | internally log what occurred.
@@ -311,13 +311,13 @@
 -- | Echo text to standard (error, when using _err variants) output. The _n
 -- variants do not print a final newline.
 echo, echo_n, echo_err, echo_n_err :: Text -> Sh ()
-echo       = traceLiftIO TIO.putStrLn
-echo_n     = traceLiftIO $ (>> hFlush stdout) . TIO.putStr
-echo_err   = traceLiftIO $ TIO.hPutStrLn stderr
-echo_n_err = traceLiftIO $ (>> hFlush stderr) . TIO.hPutStr stderr
+echo       msg = traceEcho msg >> liftIO (TIO.putStrLn msg >> hFlush stdout)
+echo_n     msg = traceEcho msg >> liftIO (TIO.putStr msg >> hFlush stdout)
+echo_err   msg = traceEcho msg >> liftIO (TIO.hPutStrLn stderr msg >> hFlush stdout)
+echo_n_err msg = traceEcho msg >> liftIO (TIO.hPutStr stderr msg >> hFlush stderr)
 
-traceLiftIO :: (Text -> IO ()) -> Text -> Sh ()
-traceLiftIO f msg = trace ("echo " `mappend` "'" `mappend` msg `mappend` "'") >> liftIO (f msg)
+traceEcho :: Text -> Sh ()
+traceEcho msg = trace ("echo " `mappend` "'" `mappend` msg `mappend` "'")
 
 -- | A helper to catch any exception (same as
 -- @... `catch` \(e :: SomeException) -> ...@).
