diff --git a/bin/spack b/bin/spack
index 354754594e60f8afd3099ea291e850db2f9d199b..5c042edd2d7b0f776bc67af2a96693e1b08a5811 100755
--- a/bin/spack
+++ b/bin/spack
@@ -126,14 +126,7 @@ def main():
     try:
         return_val = command(parser, args)
     except SpackError, e:
-        if spack.debug:
-            # In debug mode, raise with a full stack trace.
-            raise
-        elif e.long_message:
-            tty.die(e.message, e.long_message)
-        else:
-            tty.die(e.message)
-
+        e.die()
     except KeyboardInterrupt:
         sys.stderr.write('\n')
         tty.die("Keyboard interrupt.")
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index f9e795ac4237ae5b774c18c2cbd0728acc0a3647..81fbedc68974af46768d0b05a6916992a1189e38 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -280,6 +280,10 @@ def child_fun():
             # Use os._exit here to avoid raising a SystemExit exception,
             # which interferes with unit tests.
             os._exit(0)
+
+        except spack.error.SpackError, e:
+            e.die()
+
         except:
             # Child doesn't raise or return to main spack code.
             # Just runs default exception handler and exits.
diff --git a/lib/spack/spack/error.py b/lib/spack/spack/error.py
index e8fa75668279336009211dcbfab4d04842a59ae1..bfa7951a473ebddc1d5e98d25546cf14f45793a1 100644
--- a/lib/spack/spack/error.py
+++ b/lib/spack/spack/error.py
@@ -22,6 +22,10 @@
 # along with this program; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
+import os
+import sys
+import llnl.util.tty as tty
+import spack
 
 class SpackError(Exception):
     """This is the superclass for all Spack errors.
@@ -38,6 +42,17 @@ def long_message(self):
         return self._long_message
 
 
+    def die(self):
+        if spack.debug:
+            sys.excepthook(*sys.exc_info())
+            os._exit(1)
+        else:
+            tty.error(self.message)
+            if self.long_message:
+                print self.long_message
+            os._exit(1)
+
+
     def __str__(self):
         msg = self.message
         if self.long_message:
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 5dd410d0e4122e25ae83528992444b7c9e93e9df..e3d766f5827b9aba1513bbef96b7b10908657fd4 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -816,17 +816,8 @@ def real_work():
             except ProcessError, e:
                 # Annotate with location of build log.
                 e.build_log = log_path
-
-                # One of the processes returned an error code.
-                # Suppress detailed stack trace here unless in debug mode
-                if spack.debug:
-                    raise e
-                else:
-                    tty.error(e)
-
-                # Still need to clean up b/c there was an error.
                 cleanup()
-                os._exit(1)
+                raise e
 
             except:
                 # other exceptions just clean up and raise.