Python API 2.0 - Raising exceptions in a custom command

Python API 2.0 - Raising exceptions in a custom command

RFlannery1
Collaborator Collaborator
2,538 Views
5 Replies
Message 1 of 6

Python API 2.0 - Raising exceptions in a custom command

RFlannery1
Collaborator
Collaborator

I am making a custom command using the Python API 2.0.  I'm running into some problems when raising exceptions.  The traceback printed to the Script Editor looks strange, almost like it is being doubled up:

cmds.testTheThing()
# Error: My custom error message.
# # Traceback (most recent call last):
# #   File "D:/Dev/MayaTools/plugins/myTestCommand.py", line 64, in doIt
# #     raise TypeError('My custom error message.')
# # TypeError: My custom error message.
# Traceback (most recent call last):
#   File "<maya console>", line 1, in <module>
#   File "<string>", line 2, in testTheThing
# RuntimeError: My custom error message.
# # Traceback (most recent call last):
# #   File "D:/Dev/MayaTools/plugins/myTestCommand.py", line 64, in doIt
# #     raise TypeError('My custom error message.')
# # TypeError: My custom error message. #

My best guess is that my exception is being wrapped in a RuntimeError by the API.  Which leads to a more important problem: I can't get different exception types from my command.

Is anyone else having this problem?  Is it supposed to work this way?

0 Likes
Accepted solutions (1)
2,539 Views
5 Replies
Replies (5)
Message 2 of 6

lanh.hong
Alumni
Alumni

Hi rflannery,

 

I was not able to reproduce the same error as yours.

 

I wrote a really simple custom command in Python and added this piece into the doIt function.

try:
	i = len(12)
except:
	raise TypeError('Custom error message.')

However, I got this error. This is how the error should look like.

# Error: RuntimeError: file <string> line 2: TypeError: file /Users/lanh/devkit/plug-ins/plug-ins/myTestCommand.py line 40: Custom error message. #

In order for me to help, may I get a reproducible sample?

 

Thanks,

Lanh


Lanh Hong
Developer Technical Services
Autodesk Developer Network



0 Likes
Message 3 of 6

RFlannery1
Collaborator
Collaborator

Sure thing!  Here it is:

import maya.api.OpenMaya as om2

def maya_useNewAPI():
    """ The presence of this function tells Maya that the plugin produces, and
    expects to be passed, objects created using the Maya Python API 2.0. """
    pass

COMMAND_NAME = 'testTheThing'

class TestCommandException(om2.MPxCommand):
    def __init__(self):
        om2.MPxCommand.__init__(self)
    
    def isUndoable(self):
        return True
    
    def doIt(self, args):
        raise ValueError('My custom error message.')
        self.redoIt()
    
    def redoIt(self):
        print 'I did it!'
    
    def undoIt(self):
        print 'I undid it!'

def cmdCreator():
    return TestCommandException()

def initializePlugin(obj):
    plugin = om2.MFnPlugin(obj, 'MyCompany', '1.0', 'Any')
    try:
        plugin.registerCommand(COMMAND_NAME, cmdCreator)
    except:
        om2.MGlobal.displayError('Failed to register command.')

def uninitializePlugin(obj):
    plugin = om2.MFnPlugin(obj)
    try:
        plugin.deregisterCommand(COMMAND_NAME)
    except:
        om2.MGlobal.displayError('Failed to de-register command.')
0 Likes
Message 4 of 6

RFlannery1
Collaborator
Collaborator

Oh, I think I see what happened.  I can get my output to look like yours if I turn off "Show Stack Trace" in the Script Editor.  But I always keep that turned on.

0 Likes
Message 5 of 6

lanh.hong
Alumni
Alumni
Accepted solution

Oh, okay. I got similar error messages as you if I turn on Show Stack Trace. I asked one of our engineers and they said it's normal. It looks a little weird, but the way it is shown is by design so there's nothing to worry about.

 

Regards,

Lanh

 


Lanh Hong
Developer Technical Services
Autodesk Developer Network



Message 6 of 6

RFlannery1
Collaborator
Collaborator

Well that's slightly unfortunate.  I was hoping to be able to do different things based on the exception type.  Like if my command has a ValueError, the calling code can do one thing; but if there's a RuntimeError, it does something else.

 

There's probably a good reason behind it, though.  Like maybe the plugin defines a custom exception, and then the command raises that exception.  How is the calling code supposed to catch it?  What namespace does that custom exception live in?  So by wrapping all exceptions with a RuntimeError, the calling code knows what type of exception to look for.

0 Likes