Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't it work to append information in the exception message?

Why doesn't this work?

try:
    1/0
except ZeroDivisionError as e:
    e.message += ', you fool!'
    raise

The modified message is not used, even though it remains on the exception instance. Is there a working pattern for the above? Behaviour should be like my current workaround below:

try:
    1/0
except ZeroDivisionError as e:
    args = e.args
    if not args:
        arg0 = ''
    else:
        arg0 = args[0]
    arg0 += ', you fool!'
    e.args = (arg0,) + args[1:]
    raise

I'm aware of exception chaining in python3, it looks nice but unfortunately doesn't work in python2. So what is the usual recipe for re-raising an exception in python2?

Note: Because of the warnings and caveats mentioned here, I don't want to dig up the traceback and create a new exception but rather re-raise the existing exception instance.

like image 721
wim Avatar asked Oct 21 '14 14:10

wim


1 Answers

Changing e.args is the only way to do this. The implementation for BaseException.__str__ only considers the args tuple, it doesn't look at message at all:

static PyObject * 
BaseException_str(PyBaseExceptionObject *self)
{
    PyObject *out;

    switch (PyTuple_GET_SIZE(self->args)) { 
    case 0:
        out = PyString_FromString("");
        break;
    case 1:
        out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
        break;
    default:
        out = PyObject_Str(self->args);
        break;
    } 

    return out;
}

This shouldn't be too unexpected, since BaseException.message is deprecated since Python 2.6.

like image 92
dano Avatar answered Oct 24 '22 07:10

dano