8

So, I've created a custom exception that I want to call in 2 different ways (a if/else statement, and a try/except statement). Here is the custom exception:

class CustomException(Exception):   
   def __init__(self, value=None, *args, **kwargs):
     self.parameter = value
     for key, value in kwargs.items():
         setattr(self, key, value)

     for key, value in self.__dict__.items():
         print "%s => %s" % ( key, value ) 

   def __str__(self):
     return repr(self.parameter)

Here is how I am wanting to implement the custom exception:

try:
   if something:
       #make an error
       ;lsdfj
   else:
       raise CustomException('this is my custom message', file='somefile.txt', var2='something')
except Exception, e:
   raise CustomException(e)

My issues, I believe, are two fold:

1: When the standard NameError that is thrown in the try/except block (due to ;lsdfj), I want to pass CustomExceptions some extra parameters like 'file', just like the if/else implementation; how would I do that?

2: When the custom exception is raised (from the if/else statement being false), the CustomExceptions class ends up being called twice, because I raise it in the if/else block then it gets raised again within the except: section. I don't know how to get around this.

So, in the above case, I want to call CustomException when the if-statement is not true, and I want to call it when there is a standard exception thrown inside the code block... but currently, if something: evaluates to false then the CustomException will be raised twice...

So I want the custom exception to be used unilaterally throughout my code for if/else conditions, and standard python exceptions...

I know this explanation was convoluted but I'm not sure how else to explain what I'm after... Any help would be much appreciated! Thanks in advance!

sadmicrowave
  • 39,964
  • 34
  • 108
  • 180

2 Answers2

7

In order not to raise the exception twice, you should wrap the try/except block around the if statemnt only, like so:

if something:
   try:
       #make an error
       ;fdsfas
    except Exception, e:
        raise CustomException(e.message, file='somefile.txt', var2='something')
else:
    raise CustomException('this is my custom message', file='somefile.txt', var2='something')

And in order to pass the custom exception some parameters you must provide that parameters to the constructor of the class just like you did in the if/else statement.

Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
  • Haha, don't get me wrong, I'm not a fan of complication for the sake of complication, I am just worried that there may be circumstances where I need to have the try/except outside of the if/else, in which case I'm back at square one... right? – sadmicrowave Apr 09 '13 at 19:39
  • Unless you expect the condition to fail (for example `if 5 is equal to 5` will raise an invalid syntax error because `equal` is not a keyword in python) there is nothing to worry about. The code in the `if` branch is wrapped in the `try/except`, so it can't go wrong, and the `else` has got only 1 line so it can't go wrong. – Ionut Hulub Apr 09 '13 at 19:42
  • while I'm liking this solution more and more, I am experiencing the same issue as the other solution that was posted where I receive the exception traceback after my CustomException class runs for the if/else error thrown... how can I prevent the traceback from happening on the outer block? – sadmicrowave Apr 09 '13 at 20:02
  • I don't understand. Could you please expand on that? – Ionut Hulub Apr 09 '13 at 22:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27902/discussion-between-sadmicrowave-and-ionut-hulub) – sadmicrowave Apr 09 '13 at 22:29
3

You could in the except block use:

if not isinstance(e, CustomException): raise CustomException(e)

Edit:

A sys.exc_info() before the raise inside the except will successfully remove the traceback to the source of the exception i.e. NameError.

Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74
  • so, if I use this solution I also get the exception traceback when the exception is thrown due to the `NameError`which I am trying to avoid... (the custom exception thrown during the if/else statement works fine). Any way to keep the traceback from showing? – sadmicrowave Apr 09 '13 at 19:37
  • The original traceback from `NameError` seems to be suppressed but I am still getting the traceback from the `CustomException` raise event... – sadmicrowave Apr 09 '13 at 21:21
  • I'm afraid for that you will have to use [`sys.excepthook`](http://docs.python.org/2.7/library/sys.html#sys.excepthook) and send it a custom tailored `traceback instance`. – Bleeding Fingers Apr 10 '13 at 07:23
  • Where should I print the `traceback`, at bottom level or at the highest level af the call? @Bleeding Fingers – alper Apr 28 '20 at 01:00