[Answer]-Django: User-defined exception not being caught

1👍

The problem was that a different exception class was being thrown up by models.py, though the name was the same.

My settings.py did not specify the full path of the app where the models.py in question lived. After specifying the full path, the exception classes matched and the exception was caught. Thanks to all who provided great hints.

👤Neil

0👍

It’d help to see more of your code around the exception catching. From what you have shown, there are a few things to look at:

  1. I’m assuming TemplateMatchError is what you originally called MyError
  2. Your code seems unsure of how template.match returns a negative result. In serializers.py, it seems to expect a nil/false return value but the function itself raises an exception rather than returning something falsey.
  3. The code segment as you’ve shown it has bad indentation, which could be causing the failure to catch the error.

As you’ve shown it:

try:
    template.match(text)
    # Do other stuff, presumably including this:
    try:
        somethingElse()
    except TemplateMatchError as e:
        #this won't catch exceptions from template.match(text)
        continue

How I think you mean it:

try:
    template.match(text)
except TemplateMatchError as e:
    # This will be caught
    continue

Hope that helps.

0👍

are you sure that it is the same Class «TemplateMatchError» imported from the same module that you raise and you try to catch.

if this is two class with the same name but imported from diferent module, python won’t trait them as the same Exception, an then never enter your catch block.

0👍

Modify the code this way in order to verify assumptions at very near point.

    import api
    assert TemplateMatchError == api.models.TemplateMatchError
    try:
        if template.match(text):
            return attrs
    except TemplateMatchError as e:
        continue
    except Exception as e:
        assert isinstance(e, TemplateMatchError)
        import pdb; pdb.set_trace()
        pass   # if both asserts vere OK, but the exception is uncaught (not
        #        probable) you are here and see the the line debugger started
        raise   # continue by caugting in external frames

Start the testserver by the best way for debugging
python manage.py runserver --nothreading --noreload
When you see the debugger prompt (Pdb), put these commands in order to repeat it step by step:

l(ist) Enter
j(ump) <line number of the line 'try:'> Enter
b /home/uname/api/models.py:135 Enter  # breakpoint at that raise command
c(ontinue) Enter
s(tep) Enter  # press Enter five times to see steps, how the lines 
              # "except ... continue" are missed 
c(ontinue)  # to reraise and see an error page in the browser

However I think that one of asserts will fail, if DEBUG=True, and you will know more, without debugger.

Leave a comment