summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/opt-common-syn.xml1
-rw-r--r--doc/manual/opt-common.xml8
-rw-r--r--src/libexpr/primops.cc2
-rw-r--r--src/libmain/shared.cc9
-rw-r--r--src/libutil/types.hh2
-rw-r--r--src/libutil/util.cc2
6 files changed, 21 insertions, 3 deletions
diff --git a/doc/manual/opt-common-syn.xml b/doc/manual/opt-common-syn.xml
index eadc45e3a9..0412fcb6ab 100644
--- a/doc/manual/opt-common-syn.xml
+++ b/doc/manual/opt-common-syn.xml
@@ -24,6 +24,7 @@
 <arg><option>--fallback</option></arg>
 <arg><option>--readonly-mode</option></arg>
 <arg><option>--log-type</option> <replaceable>type</replaceable></arg>
+<arg><option>--show-trace</option></arg>
 <sbr />
 
 </nop>
diff --git a/doc/manual/opt-common.xml b/doc/manual/opt-common.xml
index ac967e23d0..3be9f5dd5f 100644
--- a/doc/manual/opt-common.xml
+++ b/doc/manual/opt-common.xml
@@ -305,6 +305,14 @@
 </varlistentry>
 
 
+<varlistentry><term><option>--show-trace</option></term>
+  
+  <listitem><para>Causes Nix to print out a stack trace in case of Nix
+  expression evaluation errors.</para></listitem>
+  
+</varlistentry>
+
+
 </variablelist>
 
 
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 34e7e80525..016e6abdb2 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -206,7 +206,7 @@ static Expr prim_abort(EvalState & state, const ATermVector & args)
 static Expr prim_throw(EvalState & state, const ATermVector & args)
 {
     PathSet context;
-    throw ThrownError(format("user-thrown exception: `%1%'") %
+    throw ThrownError(format("user-thrown exception: %1%") %
         evalString(state, args[0], context));
 }
 
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index e080d8cc5a..10ccb2985f 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -125,6 +125,9 @@ RemoveTempRoots::~RemoveTempRoots()
 }
 
 
+static bool showTrace = false;
+
+
 /* Initialize and reorder arguments, then call the actual argument
    processor. */
 static void initAndRun(int argc, char * * argv)
@@ -243,6 +246,8 @@ static void initAndRun(int argc, char * * argv)
             maxSilentTime = getIntArg(arg, i, args.end());
         else if (arg == "--no-build-hook")
             useBuildHook = false;
+        else if (arg == "--show-trace")
+            showTrace = true;
         else if (arg == "--option") {
             ++i; if (i == args.end()) throw UsageError("`--option' requires two arguments");
             string name = *i;
@@ -365,7 +370,9 @@ int main(int argc, char * * argv)
             % e.what() % programId);
         return 1;
     } catch (BaseError & e) {
-        printMsg(lvlError, format("error: %1%") % e.msg());
+        printMsg(lvlError, format("error: %1%%2%") % (showTrace ? e.prefix() : "") % e.msg());
+        if (e.prefix() != "" && !showTrace)
+            printMsg(lvlError, "(use `--show-trace' to show detailed location information)");
         return 1;
     } catch (std::exception & e) {
         printMsg(lvlError, format("error: %1%") % e.what());
diff --git a/src/libutil/types.hh b/src/libutil/types.hh
index fd50de00cc..f110188da1 100644
--- a/src/libutil/types.hh
+++ b/src/libutil/types.hh
@@ -24,12 +24,14 @@ using boost::format;
 class BaseError : public std::exception 
 {
 protected:
+    string prefix_; // used for location traces etc.
     string err;
 public:
     BaseError(const format & f);
     ~BaseError() throw () { };
     const char * what() const throw () { return err.c_str(); }
     const string & msg() const throw () { return err; }
+    const string & prefix() const throw () { return prefix_; }
     BaseError & addPrefix(const format & f);
 };
 
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 1cb94215ee..b2fe7e627e 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -33,7 +33,7 @@ BaseError::BaseError(const format & f)
 
 BaseError & BaseError::addPrefix(const format & f)
 {
-    err = f.str() + err;
+    prefix_ = f.str() + prefix_;
     return *this;
 }