changeset 20755:200ae1d650b7

propagate octave_execution_exception objects through try/catch blocks * gripes.h, gripes.cc (gripe_user_supplied_eval, gripe_wrong_type_arg): New overloaded functions that accept octave_execution_exception objects. * error.h, error.cc (error, verror, error_1, usage_1, debug_or_throw_exception): New overloaded functions that accept * octave_execution_exception objects. * __qp__.cc, cellfun.cc, daspk.cc, dasrt.cc, dassl.cc, data.cc, file-io.cc, graphics.cc, graphics.in.h, input.cc, load-path.cc, ls-mat-ascii.cc, lsode.cc, mex.cc, oct-handle.h, oct-map.cc, oct-stream.cc, quad.cc, rand.cc, toplev.cc, utils.cc, variables.cc, __eigs__.cc, ov-base.cc, ov-class.cc, ov-fcn-handle.cc, ov-oncleanup.cc, ov.cc, octave.cc, oct-parse.in.yy: Propagate octave_execution_exception objects through try/catch blocks.
author John W. Eaton <jwe@octave.org>
date Wed, 25 Nov 2015 15:27:48 -0500
parents 46b15c018fa5
children b4f5962b3373
files libinterp/corefcn/__qp__.cc libinterp/corefcn/cellfun.cc libinterp/corefcn/daspk.cc libinterp/corefcn/dasrt.cc libinterp/corefcn/dassl.cc libinterp/corefcn/data.cc libinterp/corefcn/error.cc libinterp/corefcn/error.h libinterp/corefcn/file-io.cc libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h libinterp/corefcn/gripes.cc libinterp/corefcn/gripes.h libinterp/corefcn/input.cc libinterp/corefcn/load-path.cc libinterp/corefcn/ls-mat-ascii.cc libinterp/corefcn/lsode.cc libinterp/corefcn/mex.cc libinterp/corefcn/oct-handle.h libinterp/corefcn/oct-map.cc libinterp/corefcn/oct-stream.cc libinterp/corefcn/quad.cc libinterp/corefcn/rand.cc libinterp/corefcn/toplev.cc libinterp/corefcn/utils.cc libinterp/corefcn/variables.cc libinterp/dldfcn/__eigs__.cc libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-oncleanup.cc libinterp/octave-value/ov.cc libinterp/octave.cc libinterp/parse-tree/oct-parse.in.yy
diffstat 34 files changed, 323 insertions(+), 140 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__qp__.cc
+++ b/libinterp/corefcn/__qp__.cc
@@ -142,9 +142,9 @@
     {
       eigH = EIG (H);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("qp: failed to compute eigenvalues of H");
+      error (e, "qp: failed to compute eigenvalues of H");
     }
 
   ColumnVector eigenvalH = real (eigH.eigenvalues ());
@@ -290,9 +290,9 @@
                 {
                   eigrH = EIG (rH);
                 }
-              catch (const octave_execution_exception&)
+              catch (const octave_execution_exception& e)
                 {
-                  error ("qp: failed to compute eigenvalues of rH");
+                  error (e, "qp: failed to compute eigenvalues of rH");
                 }
 
               ColumnVector eigenvalrH = real (eigrH.eigenvalues ());
--- a/libinterp/corefcn/cellfun.cc
+++ b/libinterp/corefcn/cellfun.cc
@@ -41,25 +41,26 @@
 #include "defun.h"
 #include "parse.h"
 #include "variables.h"
-#include "ov-colon.h"
 #include "unwind-prot.h"
 #include "gripes.h"
+#include "toplev.h"
 #include "utils.h"
 
+#include "ov-bool.h"
 #include "ov-class.h"
-#include "ov-scalar.h"
-#include "ov-float.h"
+#include "ov-colon.h"
 #include "ov-complex.h"
+#include "ov-float.h"
 #include "ov-flt-complex.h"
-#include "ov-bool.h"
-#include "ov-int8.h"
 #include "ov-int16.h"
 #include "ov-int32.h"
 #include "ov-int64.h"
-#include "ov-uint8.h"
+#include "ov-int8.h"
+#include "ov-scalar.h"
 #include "ov-uint16.h"
 #include "ov-uint32.h"
 #include "ov-uint64.h"
+#include "ov-uint8.h"
 
 #include "ov-fcn-handle.h"
 
@@ -77,12 +78,16 @@
     {
       tmp = func.do_multi_index_op (nargout, inputlist);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
       if (error_handler.is_defined ())
-        execution_error = true;
+        {
+          recover_from_exception ();
+
+          execution_error = true;
+        }
       else
-        octave_throw_execution_exception ();
+        throw e;
     }
 
   if (execution_error)
--- a/libinterp/corefcn/daspk.cc
+++ b/libinterp/corefcn/daspk.cc
@@ -79,10 +79,9 @@
         {
           tmp = daspk_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("daspk");
-          throw;
+          gripe_user_supplied_eval (e, "daspk");
         }
 
       int tlen = tmp.length ();
@@ -132,10 +131,9 @@
         {
           tmp = daspk_jac->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("daspk");
-          throw;
+          gripe_user_supplied_eval (e, "daspk");
         }
 
       int tlen = tmp.length ();
--- a/libinterp/corefcn/dasrt.cc
+++ b/libinterp/corefcn/dasrt.cc
@@ -79,10 +79,9 @@
         {
           tmp = dasrt_f->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("dasrt");
-          throw;
+          gripe_user_supplied_eval (e, "dasrt");
         }
 
       if (tmp.length () > 0 && tmp(0).is_defined ())
@@ -123,10 +122,9 @@
         {
           tmp = dasrt_cf->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("dasrt");
-          throw;
+          gripe_user_supplied_eval (e, "dasrt");
         }
 
       if (tmp.length () > 0 && tmp(0).is_defined ())
@@ -172,10 +170,9 @@
         {
           tmp = dasrt_j->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("dasrt");
-          throw;
+          gripe_user_supplied_eval (e, "dasrt");
         }
 
       int tlen = tmp.length ();
--- a/libinterp/corefcn/dassl.cc
+++ b/libinterp/corefcn/dassl.cc
@@ -79,10 +79,9 @@
         {
           tmp = dassl_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("dassl");
-          throw;
+          gripe_user_supplied_eval (e, "dassl");
         }
 
       int tlen = tmp.length ();
@@ -132,10 +131,9 @@
         {
           tmp = dassl_jac->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("dassl");
-          throw;
+          gripe_user_supplied_eval (e, "dassl");
         }
 
       int tlen = tmp.length ();
--- a/libinterp/corefcn/data.cc
+++ b/libinterp/corefcn/data.cc
@@ -1810,9 +1810,9 @@
         {
           result = fcn.do_multi_index_op (1, octave_value_list (1, ov));
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("conversion from %s to %s failed", dtype.c_str (),
+          error (e, "conversion from %s to %s failed", dtype.c_str (),
                  cname.c_str ());
         }
 
@@ -1837,9 +1837,9 @@
             {
               result = fcn.do_multi_index_op (1, octave_value_list (1, ov));
             }
-          catch (const octave_execution_exception&)
+          catch (const octave_execution_exception& e)
             {
-              error ("%s constructor failed for %s argument", dtype.c_str (),
+              error (e, "%s constructor failed for %s argument", dtype.c_str (),
                      cname.c_str ());
             }
 
@@ -1877,9 +1877,9 @@
         {
           tmp2 = fcn.do_multi_index_op (1, ovl);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("%s/%s method failed", dtype.c_str (), cattype.c_str ());
+          error (e, "%s/%s method failed", dtype.c_str (), cattype.c_str ());
         }
 
       if (tmp2.length () > 0)
--- a/libinterp/corefcn/error.cc
+++ b/libinterp/corefcn/error.cc
@@ -283,7 +283,8 @@
 }
 
 static void
-debug_or_throw_exception (bool show_stack_trace = false)
+debug_or_throw_exception (const octave_execution_exception& e,
+                          bool show_stack_trace = false)
 {
   if ((interactive || forced_interactive)
       && Vdebug_on_error && octave_call_stack::caller_user_code ())
@@ -302,21 +303,23 @@
       do_keyboard (octave_value_list ());
     }
   else
-    {
-      octave_execution_exception e;
+    throw e;
+}
+
+static void
+debug_or_throw_exception (bool show_stack_trace = false)
+{
+  octave_execution_exception e;
 
-      if (show_stack_trace
-          && octave_exception_state != octave_exec_exception)
-        {
-          std::ostringstream buf;
-          pr_where (buf, "error");
-          e.set_stack_trace (buf.str ());
-        }
+  if (show_stack_trace && octave_exception_state != octave_exec_exception)
+    {
+      std::ostringstream buf;
+      pr_where (buf, "error");
 
-      octave_exception_state = octave_exec_exception;
+      e.set_stack_trace (buf.str ());
+    }
 
-      throw e;
-    }
+  debug_or_throw_exception (e, show_stack_trace);
 }
 
 // Warning messages are never buffered.
@@ -387,7 +390,16 @@
   va_end (args);
 }
 
-void
+static void
+usage_1 (const octave_execution_exception& e, const char *id,
+         const char *fmt, va_list args)
+{
+  verror (true, std::cerr, "usage", id, fmt, args);
+
+  debug_or_throw_exception (e);
+}
+
+static void
 usage_1 (const char *id, const char *fmt, va_list args)
 {
   verror (true, std::cerr, "usage", id, fmt, args);
@@ -426,8 +438,9 @@
 }
 
 static void
-error_1 (std::ostream& os, const char *name, const char *id,
-         const char *fmt, va_list args, bool with_cfn = false)
+error_1 (const octave_execution_exception& e, std::ostream& os,
+         const char *name, const char *id, const char *fmt,
+         va_list args, bool with_cfn = false)
 {
   bool show_stack_trace = false;
 
@@ -464,7 +477,16 @@
   else
     panic ("error_1: invalid format");
 
-  debug_or_throw_exception (show_stack_trace);
+  debug_or_throw_exception (e, show_stack_trace);
+}
+
+static void
+error_1 (std::ostream& os, const char *name, const char *id,
+         const char *fmt, va_list args, bool with_cfn = false)
+{
+  octave_execution_exception e;
+
+  error_1 (e, os, name, id, fmt, args, with_cfn);
 }
 
 void
@@ -483,6 +505,21 @@
 }
 
 void
+verror (const octave_execution_exception& e, const char *fmt, va_list args)
+{
+  error_1 (e, std::cerr, "error", "", fmt, args);
+}
+
+void
+error (const octave_execution_exception& e, const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  verror (e, fmt, args);
+  va_end (args);
+}
+
+void
 verror_with_cfn (const char *fmt, va_list args)
 {
   error_1 (std::cerr, "error", "", fmt, args, true);
--- a/libinterp/corefcn/error.h
+++ b/libinterp/corefcn/error.h
@@ -29,6 +29,7 @@
 class octave_map;
 class octave_value_list;
 class unwind_protect;
+class octave_execution_exception;
 
 #define panic_impossible() \
   panic ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__)
@@ -51,6 +52,11 @@
 extern OCTINTERP_API void verror (const char *fmt, va_list args);
 extern OCTINTERP_API void error (const char *fmt, ...);
 
+extern OCTINTERP_API void verror (const octave_execution_exception&,
+                                  const char *fmt, va_list args);
+extern OCTINTERP_API void error (const octave_execution_exception&,
+                                 const char *fmt, ...);
+
 extern OCTINTERP_API void verror_with_cfn (const char *fmt, va_list args);
 extern OCTINTERP_API void error_with_cfn (const char *fmt, ...);
 
--- a/libinterp/corefcn/file-io.cc
+++ b/libinterp/corefcn/file-io.cc
@@ -1332,9 +1332,9 @@
       oct_data_conv::string_to_data_type (prec, block_size,
                                           input_type, output_type);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("fread: invalid PRECISION specified");
+      error (e, "fread: invalid PRECISION specified");
     }
 
   int skip = 0;
@@ -1343,9 +1343,9 @@
     {
       skip = skip_arg.int_value (true);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("fread: SKIP must be an integer");
+      error (e, "fread: SKIP must be an integer");
     }
 
   std::string arch = arch_arg.xstring_value ("fread: ARCH architecture type must be a string");
@@ -1590,9 +1590,9 @@
     {
       oct_data_conv::string_to_data_type (prec, block_size, output_type);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("fwrite: invalid PRECISION specified");
+      error (e, "fwrite: invalid PRECISION specified");
     }
 
   int skip = 0;
@@ -1601,9 +1601,9 @@
     {
       skip = skip_arg.int_value (true);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("fwrite: SKIP must be an integer");
+      error (e, "fwrite: SKIP must be an integer");
     }
 
   std::string arch = arch_arg.xstring_value ("fwrite: ARCH architecture type must be a string");
--- a/libinterp/corefcn/graphics.cc
+++ b/libinterp/corefcn/graphics.cc
@@ -1264,9 +1264,9 @@
                       return true;
                     }
                 }
-              catch (const octave_execution_exception&)
+              catch (const octave_execution_exception& e)
                 {
-                  error ("invalid value for color property \"%s\" (value = %s)",
+                  error (e, "invalid value for color property \"%s\" (value = %s)",
                          get_name ().c_str (), s.c_str ());
                 }
             }
@@ -2863,9 +2863,9 @@
             {
               bgo.set (pname, q->second);
             }
-          catch (const octave_execution_exception&)
-            {
-              error ("error setting default property %s", pname.c_str ());
+          catch (const octave_execution_exception& e)
+            {
+              error (e, "error setting default property %s", pname.c_str ());
             }
         }
     }
@@ -10191,9 +10191,9 @@
                                                 integer_figure_handle,
                                                 false, false);
         }
-      catch (const octave_execution_exception&)
-        {
-          error ("__go%s__: unable to create graphics handle",
+      catch (const octave_execution_exception& e)
+        {
+          error (e, "__go%s__: unable to create graphics handle",
                  go_name.c_str ());
         }
 
--- a/libinterp/corefcn/graphics.in.h
+++ b/libinterp/corefcn/graphics.in.h
@@ -806,9 +806,9 @@
           {
             nda = val.array_value ();
           }
-        catch (const octave_execution_exception&)
+        catch (const octave_execution_exception& e)
           {
-            error ("set: invalid string property value for \"%s\"",
+            error (e, "set: invalid string property value for \"%s\"",
                    get_name ().c_str ());
           }
 
@@ -1700,9 +1700,9 @@
       {
         new_kids = val.matrix_value ();
       }
-    catch (const octave_execution_exception&)
+    catch (const octave_execution_exception& e)
       {
-        error ("set: children must be an array of graphics handles");
+        error (e, "set: children must be an array of graphics handles");
       }
 
     octave_idx_type nel = new_kids.numel ();
--- a/libinterp/corefcn/gripes.cc
+++ b/libinterp/corefcn/gripes.cc
@@ -86,7 +86,16 @@
 void
 gripe_user_supplied_eval (const char *name)
 {
-  error ("%s: evaluation of user-supplied function failed", name);
+  octave_execution_exception e;
+
+  gripe_user_supplied_eval (e, name);
+}
+
+void
+gripe_user_supplied_eval (const octave_execution_exception& e,
+                          const char *name)
+{
+  error (e, "%s: evaluation of user-supplied function failed", name);
 }
 
 void
@@ -134,8 +143,17 @@
 void
 gripe_wrong_type_arg (const char *name, const char *s, bool is_error)
 {
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, name, s, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const char *s, bool is_error)
+{
   if (is_error)
-    error ("%s: wrong type argument '%s'", name, s);
+    error (e, "%s: wrong type argument '%s'", name, s);
   else
     warning ("%s: wrong type argument '%s'", name, s);
 }
@@ -143,30 +161,68 @@
 void
 gripe_wrong_type_arg (const char *name, const std::string& s, bool is_error)
 {
-  gripe_wrong_type_arg (name, s.c_str (), is_error);
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, name, s.c_str (), is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const std::string& s, bool is_error)
+{
+  gripe_wrong_type_arg (e, name, s.c_str (), is_error);
 }
 
 void
 gripe_wrong_type_arg (const char *name, const octave_value& tc,
                       bool is_error)
 {
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, name, tc, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const octave_value& tc,
+                      bool is_error)
+{
   std::string type = tc.type_name ();
 
-  gripe_wrong_type_arg (name, type, is_error);
+  gripe_wrong_type_arg (e, name, type, is_error);
 }
 
 void
 gripe_wrong_type_arg (const std::string& name, const octave_value& tc,
                       bool is_error)
 {
-  gripe_wrong_type_arg (name.c_str (), tc, is_error);
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, name, tc, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const std::string& name, const octave_value& tc,
+                      bool is_error)
+{
+  gripe_wrong_type_arg (e, name.c_str (), tc, is_error);
 }
 
 void
 gripe_wrong_type_arg (const char *s, bool is_error)
 {
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, s, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *s, bool is_error)
+{
   if (is_error)
-    error ("wrong type argument '%s'", s);
+    error (e, "wrong type argument '%s'", s);
   else
     warning ("wrong type argument '%s'", s);
 }
@@ -174,15 +230,33 @@
 void
 gripe_wrong_type_arg (const std::string& s, bool is_error)
 {
-  gripe_wrong_type_arg (s.c_str (), is_error);
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, s, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const std::string& s, bool is_error)
+{
+  gripe_wrong_type_arg (e, s.c_str (), is_error);
 }
 
 void
 gripe_wrong_type_arg (const octave_value& tc, bool is_error)
 {
+  octave_execution_exception e;
+
+  gripe_wrong_type_arg (e, tc, is_error);
+}
+
+void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const octave_value& tc, bool is_error)
+{
   std::string type = tc.type_name ();
 
-  gripe_wrong_type_arg (type, is_error);
+  gripe_wrong_type_arg (e, type, is_error);
 }
 
 void
--- a/libinterp/corefcn/gripes.h
+++ b/libinterp/corefcn/gripes.h
@@ -28,6 +28,7 @@
 #include "lo-array-gripes.h"
 
 class octave_value;
+class octave_execution_exception;
 
 extern OCTINTERP_API void
 gripe_not_supported (const char *);
@@ -58,6 +59,10 @@
 gripe_user_supplied_eval (const char *name);
 
 extern OCTINTERP_API void
+gripe_user_supplied_eval (const octave_execution_exception& e,
+                          const char *name);
+
+extern OCTINTERP_API void
 gripe_user_returned_invalid (const char *name);
 
 extern OCTINTERP_API void
@@ -83,27 +88,59 @@
                       bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const char *s,
+                      bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const char *name, const std::string& s,
                       bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const std::string& s,
+                      bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const char *name, const octave_value& tc,
                       bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *name, const octave_value& tc,
+                      bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const std::string& name, const octave_value& tc,
                       bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const std::string& name, const octave_value& tc,
+                      bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const char *s, bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const char *s, bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const std::string& s, bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const std::string& s, bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg (const octave_value& tc, bool is_error = true);
 
 extern OCTINTERP_API void
+gripe_wrong_type_arg (const octave_execution_exception& e,
+                      const octave_value& tc, bool is_error = true);
+
+extern OCTINTERP_API void
 gripe_wrong_type_arg_for_unary_op (const octave_value& op);
 
 extern OCTINTERP_API void
--- a/libinterp/corefcn/input.cc
+++ b/libinterp/corefcn/input.cc
@@ -647,9 +647,8 @@
           if (! stack_trace.empty ())
             std::cerr << stack_trace;
 
+          // Ignore errors when in debugging mode;
           recover_from_exception ();
-
-          // Ignore errors when in debugging mode;
         }
     }
 }
--- a/libinterp/corefcn/load-path.cc
+++ b/libinterp/corefcn/load-path.cc
@@ -93,8 +93,10 @@
             }
           catch (const octave_execution_exception&)
             {
-              // Skip updating if we don't know where we are, but
+              // Skip updating if we don't know where we are but
               // don't treat it as an error.
+
+              recover_from_exception ();
             }
         }
       else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked)
@@ -159,7 +161,10 @@
         }
       catch (const octave_execution_exception&)
         {
-          // Skip updating if we don't know where we are.
+          // Skip updating if we don't know where we are but don't treat
+          // it as an error.
+
+          recover_from_exception ();
         }
     }
   else
--- a/libinterp/corefcn/ls-mat-ascii.cc
+++ b/libinterp/corefcn/ls-mat-ascii.cc
@@ -59,6 +59,7 @@
 #include "pager.h"
 #include "pt-exp.h"
 #include "sysdep.h"
+#include "toplev.h"
 #include "unwind-prot.h"
 #include "utils.h"
 #include "variables.h"
@@ -375,8 +376,10 @@
     {
       m = val.matrix_value (true);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
+      recover_from_exception ();
+
       success = false;
     }
 
--- a/libinterp/corefcn/lsode.cc
+++ b/libinterp/corefcn/lsode.cc
@@ -76,10 +76,9 @@
         {
           tmp = lsode_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("lsode");
-          throw;
+          gripe_user_supplied_eval (e, "lsode");
         }
 
       if (tmp.length () > 0 && tmp(0).is_defined ())
@@ -119,10 +118,9 @@
         {
           tmp = lsode_jac->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("lsode");
-          throw;
+          gripe_user_supplied_eval (e, "lsode");
         }
 
       if (tmp.length () > 0 && tmp(0).is_defined ())
--- a/libinterp/corefcn/mex.cc
+++ b/libinterp/corefcn/mex.cc
@@ -3112,6 +3112,8 @@
     }
   catch (const octave_execution_exception&)
     {
+      recover_from_exception ();
+
       execution_error = true;
     }
 
@@ -3173,6 +3175,8 @@
     }
   catch (const octave_execution_exception&)
     {
+      recover_from_exception ();
+
       execution_error = true;
     }
 
--- a/libinterp/corefcn/oct-handle.h
+++ b/libinterp/corefcn/oct-handle.h
@@ -46,9 +46,9 @@
           {
             val = a.double_value ();
           }
-        catch (const octave_execution_exception&)
+        catch (const octave_execution_exception& e)
           {
-            error ("invalid handle");
+            error (e, "invalid handle");
           }
       }
   }
--- a/libinterp/corefcn/oct-map.cc
+++ b/libinterp/corefcn/oct-map.cc
@@ -650,9 +650,9 @@
                                      new_map_list[i], perm);
         }
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("cat: field names mismatch in concatenating structs");
+      error (e, "cat: field names mismatch in concatenating structs");
     }
 }
 
@@ -1001,9 +1001,9 @@
         {
           rhs1 = rhs.orderfields (*this, perm);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("incompatible fields in struct assignment");
+          error (e, "incompatible fields in struct assignment");
         }
 
       assert (rhs1.xkeys.is_same (xkeys));
@@ -1049,9 +1049,9 @@
         {
           rhs1 = rhs.orderfields (*this, perm);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("incompatible fields in struct assignment");
+          error (e, "incompatible fields in struct assignment");
         }
 
       assert (rhs1.xkeys.is_same (xkeys));
@@ -1097,9 +1097,9 @@
         {
           rhs1 = rhs.orderfields (*this, perm);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("incompatible fields in struct assignment");
+          error (e, "incompatible fields in struct assignment");
         }
 
       assert (rhs1.xkeys.is_same (xkeys));
--- a/libinterp/corefcn/oct-stream.cc
+++ b/libinterp/corefcn/oct-stream.cc
@@ -50,6 +50,7 @@
 #include "oct-stdstrm.h"
 #include "oct-stream.h"
 #include "oct-obj.h"
+#include "toplev.h"
 #include "utils.h"
 
 // Possible values for conv_err:
@@ -73,6 +74,8 @@
     }
   catch (const octave_execution_exception&)
     {
+      recover_from_exception ();
+
       conv_err = 1;
     }
 
--- a/libinterp/corefcn/quad.cc
+++ b/libinterp/corefcn/quad.cc
@@ -73,10 +73,9 @@
         {
           tmp = quad_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("quad");
-          throw;
+          gripe_user_supplied_eval (e, "quad");
         }
 
       if (tmp.length () && tmp(0).is_defined ())
@@ -112,10 +111,9 @@
         {
           tmp = quad_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("quad");
-          throw;
+          gripe_user_supplied_eval (e, "quad");
         }
 
       if (tmp.length () && tmp(0).is_defined ())
--- a/libinterp/corefcn/rand.cc
+++ b/libinterp/corefcn/rand.cc
@@ -214,9 +214,9 @@
               {
                 iv = tmp.int_vector_value (true);
               }
-            catch (const octave_execution_exception&)
+            catch (const octave_execution_exception& e)
               {
-                error ("%s: dimensions must be a scalar or array of integers", fcn);
+                error (e, "%s: dimensions must be a scalar or array of integers", fcn);
               }
 
             octave_idx_type len = iv.numel ();
--- a/libinterp/corefcn/toplev.cc
+++ b/libinterp/corefcn/toplev.cc
@@ -642,13 +642,16 @@
       catch (const octave_interrupt_exception&)
         {
           recover_from_exception ();
+
           octave_stdout << "\n";
+
           if (quitting_gracefully)
             return exit_status;
         }
       catch (const index_exception& e)
         {
           recover_from_exception ();
+
           std::cerr << "error: unhandled index exception: "
                     << e.message () << " -- trying to return to prompt"
                     << std::endl;
@@ -672,6 +675,7 @@
       catch (const std::bad_alloc&)
         {
           recover_from_exception ();
+
           std::cerr << "error: out of memory -- trying to return to prompt"
                     << std::endl;
         }
@@ -1052,9 +1056,9 @@
             {
               return_output = args(1).is_true ();
             }
-          catch (const octave_execution_exception&)
+          catch (const octave_execution_exception& e)
             {
-              error ("system: RETURN_OUTPUT must be boolean value true or false");
+              error (e, "system: RETURN_OUTPUT must be boolean value true or false");
             }
         }
 
--- a/libinterp/corefcn/utils.cc
+++ b/libinterp/corefcn/utils.cc
@@ -1282,6 +1282,7 @@
                 {
                   std::string idx = e.idx ();
                   std::string msg = e.details ();
+
                   error ("dims_to_numel: Invalid IDX %s. %s",
                          idx.c_str (), msg.c_str ());
                 }
@@ -1449,6 +1450,8 @@
     }
   catch (const octave_execution_exception&)
     {
+      recover_from_exception ();
+
       retval = false;
     }
 
--- a/libinterp/corefcn/variables.cc
+++ b/libinterp/corefcn/variables.cc
@@ -374,7 +374,7 @@
     }
   catch (const octave_execution_exception&)
     {
-      // Ignore errors.
+      recover_from_exception ();
     }
 
   return retval;
--- a/libinterp/dldfcn/__eigs__.cc
+++ b/libinterp/dldfcn/__eigs__.cc
@@ -62,9 +62,9 @@
         {
           tmp = eigs_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("eigs");
+          gripe_user_supplied_eval (e, "eigs");
         }
 
       if (tmp.length () && tmp(0).is_defined ())
@@ -102,9 +102,9 @@
         {
           tmp = eigs_fcn->do_multi_index_op (1, args);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          gripe_user_supplied_eval ("eigs");
+          gripe_user_supplied_eval (e, "eigs");
         }
 
       if (tmp.length () && tmp(0).is_defined ())
--- a/libinterp/octave-value/ov-base.cc
+++ b/libinterp/octave-value/ov-base.cc
@@ -464,9 +464,9 @@
       { \
         d = double_value (frc_str_conv); \
       } \
-    catch (const octave_execution_exception&) \
+    catch (const octave_execution_exception& e) \
       { \
-        gripe_wrong_type_arg ("octave_base_value::" #F "_value ()", type_name ()); \
+        gripe_wrong_type_arg (e, "octave_base_value::" #F "_value ()", type_name ()); \
       } \
  \
     if (require_int && D_NINT (d) != d) \
@@ -502,9 +502,9 @@
     {
       d = double_value (frc_str_conv);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      gripe_wrong_type_arg ("octave_base_value::nint_value ()", type_name ());
+      gripe_wrong_type_arg (e, "octave_base_value::nint_value ()", type_name ());
     }
 
   if (xisnan (d))
--- a/libinterp/octave-value/ov-class.cc
+++ b/libinterp/octave-value/ov-class.cc
@@ -1106,6 +1106,8 @@
             }
           catch (const octave_execution_exception&)
             {
+              recover_from_exception ();
+
               execution_error = true;
             }
 
--- a/libinterp/octave-value/ov-fcn-handle.cc
+++ b/libinterp/octave-value/ov-fcn-handle.cc
@@ -2084,6 +2084,8 @@
                                 }
                               catch (const octave_execution_exception&)
                                 {
+                                  recover_from_exception ();
+
                                   bad = true;
                                 }
                             }
--- a/libinterp/octave-value/ov-oncleanup.cc
+++ b/libinterp/octave-value/ov-oncleanup.cc
@@ -85,12 +85,12 @@
     }
   catch (const octave_interrupt_exception&)
     {
-      // Swallow the interrupt.
+      recover_from_exception ();
+
       warning ("onCleanup: interrupt occured in cleanup action");
     }
   catch (const octave_execution_exception&)
     {
-      // Propagate the error.
       throw;
     }
   catch (...) // Yes, the black hole. We're in a d-tor.
--- a/libinterp/octave-value/ov.cc
+++ b/libinterp/octave-value/ov.cc
@@ -1873,17 +1873,17 @@
       { \
         retval = FCN (); \
       } \
-    catch (const octave_execution_exception&) \
+    catch (const octave_execution_exception& e) \
       { \
         if (fmt) \
           { \
             va_list args; \
             va_start (args, fmt); \
-            verror (fmt, args); \
+            verror (e, fmt, args); \
             va_end (args); \
           } \
  \
-        throw; \
+        throw e; \
       } \
  \
     return retval; \
@@ -2474,18 +2474,18 @@
         {
           m_base = base.matrix_value (true);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("invalid base value in colon expression");
+          error (e, "invalid base value in colon expression");
         }
 
       try
         {
           m_limit = limit.matrix_value (true);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("invalid limit value in colon expression");
+          error (e, "invalid limit value in colon expression");
         }
 
       try
@@ -2494,9 +2494,9 @@
                          ? increment.matrix_value (true)
                          : Matrix (1, 1, 1.0));
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("invalid increment value in colon expression");
+          error (e, "invalid increment value in colon expression");
         }
 
       bool base_empty = m_base.is_empty ();
--- a/libinterp/octave.cc
+++ b/libinterp/octave.cc
@@ -282,13 +282,16 @@
   catch (const octave_interrupt_exception&)
     {
       recover_from_exception ();
+
       octave_stdout << "\n";
+
       if (quitting_gracefully)
         clean_up_and_exit (exit_status);
     }
   catch (const octave_execution_exception&)
     {
       recover_from_exception ();
+
       gripe_safe_source_exception (file_name, "unhandled execution exception");
     }
 }
@@ -397,13 +400,16 @@
   catch (const octave_interrupt_exception&)
     {
       recover_from_exception ();
+
       octave_stdout << "\n";
+
       if (quitting_gracefully)
         clean_up_and_exit (exit_status);
     }
   catch (const octave_execution_exception&)
     {
       recover_from_exception ();
+
       std::cerr << "error: unhandled execution exception -- eval failed"
                 << std::endl;
     }
@@ -865,6 +871,8 @@
         }
       catch (const octave_execution_exception&)
         {
+          recover_from_exception ();
+
           parse_status = 1;
         }
 
@@ -897,6 +905,8 @@
         }
       catch (const octave_execution_exception&)
         {
+          recover_from_exception ();
+
           exit_status = 1;
         }
 
--- a/libinterp/parse-tree/oct-parse.in.yy
+++ b/libinterp/parse-tree/oct-parse.in.yy
@@ -4494,9 +4494,9 @@
       fcn = parse_fcn_file (file_full_name, file_name, "", "",
                             require_file, true, false, false, warn_for);
     }
-  catch (const octave_execution_exception&)
+  catch (const octave_execution_exception& e)
     {
-      error ("source: error sourcing file '%s'", file_full_name.c_str ());
+      error (e, "source: error sourcing file '%s'", file_full_name.c_str ());
     }
 
   if (fcn && fcn->is_user_script ())
@@ -4634,9 +4634,9 @@
         {
           maybe_missing_function_hook (name);
         }
-      catch (const octave_execution_exception&)
+      catch (const octave_execution_exception& e)
         {
-          error ("feval: function '%s' not found", name.c_str ());
+          error (e, "feval: function '%s' not found", name.c_str ());
         }
     }