bugGNU Octave - Bugs: bug #40828, Exception handling: MException...


bug #40828: Exception handling: MException object functions

Submitter:  Nir Krakauer <nir_krakauer>
Submitted:  Fri 06 Dec 2013 08:09:05 PM UTC
Category:  Interpreter Severity:  1 - Wish
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  None Assigned to:  None
Originator Name:  Nir Krakauer Open/Closed:  * Open
Release:  * dev Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)

Comment Type & Canned Response:


( Jump to the original submission )

Sat 01 Jan 2022 10:10:34 AM UTC, comment #14: 

Re-assigning to dev.

Markus Mützel <mmuetzel>
Project Member
Wed 29 Dec 2021 07:50:00 PM UTC, comment #13: 

It all makes sense (I presume there's a typo in the regexp ')'->'0', which makes me wonder if there is a private function that would perform this check (as I guess it also takes place with error/warning)?).

Just checked with Matlab by adding a MException class or function in the path but the built-in version seems to always have priority and there is no way to shadow it.

With your two changes and setting back setAccess = private to hasBeenCaught, the implementation of MException seems complete and could exist before "catch ME" is upgraded.

Guillaume <gyom>
Wed 29 Dec 2021 07:14:58 PM UTC, comment #12: 

@Guillaume: Yes, I forgot to include the small change I made to your MException.m:

This part changes it to set hasBeenCaught to true if the constructor is called with 2 arguments.  Maybe I should have used the value of the second argument, but I just needed to set hasBeenCaught to true.

--- MException.m        2021-12-28 09:18:56.304544115 -0500
+++ MException.m        2021-12-28 09:57:26.453914848 -0500
@@ -47,11 +47,16 @@
   methods (Access = public)

     function this = MException (id, template, varargin)
-      if (nargin == 1 && isstruct (id))
-        # Matlab does not have this constructor. Used internally by last().
+      if ((nargin == 1 || nargin == 2) && isstruct (id))
+        # Matlab does not have this constructor. Used internally by
+        # last() and by the evaluator in constructing exception
+        # objects in CATCH blocks.
         this.identifier = id.identifier;
         this.message = id.message;
         this.stack = id.stack;
+        if (nargin == 2)
+          this.hasBeenCaught = true;
+        endif
         if (nargin < 2 || nargout > 1)
           print_usage ();

I also needed this change to accept Octave's error identifiers that include '-' characters:

--- MException.m        2021-12-28 09:18:56.304544115 -0500
+++ MException.m        2021-12-28 09:57:26.453914848 -0500
@@ -65,7 +70,10 @@
       if (! ischar (this.message) || (! isempty (this.message) && ! isrow (this.message)))
         error ("MException: Message must be a row string.");
-      if (! isempty(this.identifier) && isempty (regexp(this.identifier,'^([a-zA-Z]\w*)(:[a-zA-Z]\w*)+$')))
+      if (! isempty (this.identifier)
+          && isempty (regexp (this.identifier,
+                              "^([A-Za-z][A-Za-z)-9_-]*)(:[A-Za-z][A-Za-z0-9_-]*)*$")))
         error ("MException: Invalid identifier.");

When we get this working it would probably be best to find a way to construct the MException object without needing to evaluate a function so that Octave will always correctly construct these objects even if the MException function is shadowed by some user-defined function.  I mean, I assume that Matlab doesn't call a user-defined MException constructor if it happens to appear somewhere in the the path, right?

John W. Eaton <jwe>
Project Administrator
Wed 29 Dec 2021 05:52:41 PM UTC, comment #11: 

Thank you. I searched where the ME variable in "catch ME" was defined but couldn't find it. Your code is instructive to me as I see how you directly call the MException constructor. The MException class defines a constructor with an error structure as input but this is not something that Matlab does. With "ovl (err_map, true)", does it mean you changed the constructor to also pass the value of the property hasBeenCaught? That could be the way to go to prevent having to set public access to that property.

Guillaume <gyom>
Tue 28 Dec 2021 05:40:26 PM UTC, comment #10: 

I hoped to integrate MException in the Octave evaluator before now.  But at this point it does seem better to postpone this feature until version 8.

If you want to experiment with it, the attached change will make CATCH blocks create MException objects instead of simple structs.  This change is simple enough but there are many test failures related to MException when running the test suite after this change.  It seems that Octave is failing to find the MException constructor.  I'm not sure what triggers that.  There was some discussion of a similar problem in bug #60791 but the patch posted there did not solve the problem for me.

(file #52580)

John W. Eaton <jwe>
Project Administrator
Tue 28 Dec 2021 01:15:34 PM UTC, comment #9: 

No, it's not and interest seems low so Octave 7 can definitely be released without this.
Currently "catch ME" returns a struct but will hopefully return a MException object in the future. As it is a backward-compatibility issue, could this future change be mentioned in the news so that it can take place in Octave 8?

Guillaume <gyom>
Fri 24 Dec 2021 10:15:52 AM UTC, comment #8: 

Is this really blocking the Octave 7 release? What minimum steps would be necessary to get this ready for Octave 7?

Markus Mützel <mmuetzel>
Project Member
Fri 22 Oct 2021 08:39:16 AM UTC, comment #7: 

I attach a suggestion of implementation for the MException class.

I notice that Matlab's identifiers cannot contain a "-" while Octave allows (and uses it), e.g. "Octave:undefined-function". Current checks on identifiers are strict so "-" will have to be added as a valid character for Octave use.

There is a hidden, public setAccess property hasBeenCaught that should be set to true when a MException object has been created from a try/catch.

(file #52144)

Guillaume <gyom>
Thu 21 Oct 2021 02:19:16 PM UTC, comment #6: 

My question for getReport() was to know whether there would be a way to capture the text that is sent to std::cerr in libinterp/corefcn/error.cc: error_system::display_exception (const execution_exception& ee) so that it can be returned as a string instead of raising an exception.

Guillaume <gyom>
Wed 20 Oct 2021 08:58:58 PM UTC, comment #5: 

I don't understand what you mean by "the output of rethrow () as a string".

For the hasBeenCaught flag, it seems like the right thing would be for the code that evaluates the catch part of try/catch statements to set that flag in the MException object.  It could do that by evaluating a classdef method or by setting the property directly using some internal classdef function.  I'm not sure what will be easiest without trying to add that feature.

I don't know what would cause the "class not found" error.

John W. Eaton <jwe>
Project Administrator
Wed 20 Oct 2021 08:02:33 PM UTC, comment #4: 

Thanks, it seems the MException class doesn't do much - it's mainly a wrapper around built-in rethrow () defined for structs. For the getReport method, I would need the output of rethrow () as a string, would there be a way to get access to that?

In Matlab, rethrow () only works in the context of "try/catch ME" so the ME object in that instance should have a private flag hasBeenCaught set to true so that we can reproduce the same behavior. Do we need to define an accessor to set that property or could the code defining "try/catch ME" do that directly?

I also notice that, when run twice, "test MException" will return an error:

class not found: MException

It doesn't seem to be specific to this class (i.e. handling of errors). I'll try to come up with a small class reproducing the issue.

(file #52136)

Guillaume <gyom>
Tue 19 Oct 2021 03:47:58 PM UTC, comment #3: 

Yes, I think it would be good to define a classdef object for exceptions.

John W. Eaton <jwe>
Project Administrator
Tue 19 Oct 2021 02:39:45 PM UTC, comment #2: 

I am looking at MException objects and this seems to be the only open bug report referencing them: would it make sense starting an implementation of a classdef-based MException class?


Then "try, catch ME" could be modified to return an MException object instead of a struct.

Guillaume <gyom>
Tue 12 Apr 2016 04:37:09 PM UTC, comment #1: 

Is there any update on this? I started porting matlab code to octave 4.0.1 and our exception code is incompatible. In Matlab the exception is a class with the functions throw, rethrow, addCause, etc.

A typical use case for us is:
catch ME1
    ME2 = MException('failedInstantiate', sprintf('Failed to create object of type %s', type ));
    ME1 = ME1.addCause( ME2 );

as well as the ME1.getReport() function to format the .message and .stack trace into a nice string to print.

Ivo <icouckuy>
Fri 06 Dec 2013 08:09:05 PM UTC, original submission:  

Following up on https://savannah.gnu.org/bugs/?func=detailitem&item_id=33217 , Octave doesn't recognize functions such as throw and rethrow used in Matlab's new exception handling syntax.

[cf. http://www.mathworks.com/help/matlab/matlab_prog/capture-information-about-errors.html for Matlab's documentation]

Nir Krakauer <nir_krakauer>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Attached Files
file #52144:  MException.m added by gyom (12KiB - text/x-objcsrc)
file #52136:  MException.m added by gyom (9KiB - text/x-objcsrc)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by siko1056 (Updated the item)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by icouckuy (Posted a comment)
  • -email is unavailable- added by nir_krakauer (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only project members can vote.





    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-01-01 mmuetzel Release7.0.90 dev
    2021-12-28 jwe Attached File- Added mexception-evaluator-patch.txt, #52580
    2021-11-17 siko1056 Releasedev 7.0.90
    2021-10-22 gyom Attached File- Added MException.m, #52144
    2021-10-21 mtmiller Carbon-CopyRemoved 80942 -
    2021-10-20 gyom Attached File- Added MException.m, #52136
    2016-11-16 mtmiller Severity3 - Normal 1 - Wish
        Release3.6.4 dev

    Back to the top

    Powered by Savane 3.9