Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customizing exceptions in python? writing logs in custom exception class?

I am customizing exceptions in my python code. I have inherited exception class in to other and now defining some custom errors as classes derived from my custom exception class like this:

class DataCollectorError(Exception): pass
class ParamNullError(DataCollectorError) : pass
class ParamInvalidTypeError(DataCollectorError) : pass

I am raising these exceptions in my python function like:

def READ_METER_DATA (regIndex, numRegisters, slaveUnit):
    try:
        if not regIndex:
            raise ParamNullError, "register index is null"

        if not numRegisters:
            raise ParamNullError, "number of registers should not be null"

        if not slaveUnit:
            raise ParamNullError, "Meter Id should not be null"

and logging error like :

except DataCollectorError as d:
    lgr.error('DataCollector Error(READ_METER_DATA): '+d.args[0])
    print 'DataCollector Error:(READ_METER_DATA)', d.args[0]
except:
    lgr.error('Unexpected Error: ', sys.exc_info())
    print 'Unexpected Error: ', sys.exc_info()
    pass

but this defeats purpose of unit testing script as it doesn't whether exception raised bcz it is being catched by my catch block before my unit test script knows it. so i wanted to log these errors in base class itself -

Class ParamNullError(DataCollectorError):
    <----here----------->
    pass 

can anybody tell me how to fetch that string passed while raising exception?

like image 842
Inderpal Singh Avatar asked Oct 27 '25 14:10

Inderpal Singh


2 Answers

Simply extend your error-class with an __init__ and an __str__ method.

Example:

class DataCollectorError(Exception):
    def __init__(self, msg=''):
        self.msg = msg
        log(msg)  # use your logging things here

    def __str__(self):
        return self.msg

Use msg='' because then you don't need to always specify a message.

like image 141
TobiMarg Avatar answered Oct 29 '25 04:10

TobiMarg


Don't.

Factor out the calls you need to unit test, and move your exception handler out:

try:
     testableFunctionCall()
except:
     lgr.exception('Unexpected Error')

and test testableFunctionCall().

Alternatively, use the testfixtures library to test the logging itself:

from testfixtures import LogCapture
with LogCapture() as l:
    callFunctionUnderTest()

l.check(
     ('packagename', 'ERROR', 'DataCollector Error(READ_METER_DATA): foobar'),
)
like image 23
Martijn Pieters Avatar answered Oct 29 '25 04:10

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!