Unclear as to how to raise a Python exception

I have the following email routine in a program that's running against ArcGIS10:

def eMail(num, countFile):
# Open the completed output file for reading.
    try:
        if (num == 1):
            outputR = open(countFile, "r")
            msg = MIMEText(outputR.read())
           
        else:
            msg = MIMEText("TEST -- System Generated Message: There were no non-LR Layers updated in Prod 5171")

        outputR.close()
        mailRecipients = []
        for name in recipients:
            name += "@loudoun.gov"
            mailRecipients.append(name)

        COMMASPACE = ', '

        msg['Subject'] = 'NonLR Update Prod2Browse : Success'
        msg['From'] = 'gissched@loudoun.gov'
        msg['To'] = COMMASPACE.join(mailRecipients)

## Send the message via our own SMTP server, but don't include the envelope header.
        s = smtplib.SMTP('smtprelay.prod.loudoun.local', '25')

        s.sendmail('gissched@loudoun.gov', mailRecipients, msg.as_string())
        s.quit();

    except:
        raise ConnErr

    finally:
        del msg, s

The recipients variable is defined as follows:

recepients = ["Charles.Shore","Saraswathi.Emani"]

and the error handling class is:

class ConnErr():
    def __init__(self, prev, next, msg):
        self.prev = prev
        self.next = next
        self.msg = msg

        errF = open(errFile, "w")
        errF.write(str(CURRTIME) + '\n\n')
        errF.write(self.msg)
        errF.close()
        del errF

If there are data layers in a specified text file, then num = 1 and the first message (showing the record counts) is defined.  Otherwise, num = 2 and the second message is defined.

The last few times I tested this (several weeks ago), this all worked fine.  However, now I'm having two problems:

1) In the finally clause, I'm told I can't delete 'msg' and 's' before they're defined.
2) The ConnErr class is looking for 4 arguments.  I understand that 'prev' and 'next' refer to transition states, but I haven't found any explanation in the literature as to what those states should be.  Should the 3 arguments (excluding 'self') be strings?

Finally, why should this code work fine one week, then crash several weeks later?  
cshore12Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

HonorGodSoftware EngineerCommented:
You might consider testing for the existence of "msg" and "s" before you try to delete them.

e.g., perhaps something like:
>>> if 'msg' in locals() :
...   print 'yes'
... else :
...   print 'no'
...
no
>>>

Open in new window

0
cshore12Author Commented:
Can someone at least tell me what to use for 'prev' and 'next'?
0
HonorGodSoftware EngineerCommented:
I would consider defining ConnErr something like this
class ConnErr( Exception ) :
    def __init__( self, msg ) :
        errF = open( errFile, "w" )
        errF.write( str(CURRTIME) + '\n\n')
        errF.write( msg )
        errF.close()
        del( errF )

Open in new window

then you wouldn't need a prev / next
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

cshore12Author Commented:
Thanks, HG, I tried that and it worked fine.

However, for my own edification, I'd still like to have a solid example of how to use 'prev' and 'next'.  The documentation uses trivial examples like 'foo' and 'bar', which really doesn't tell me what anything about the concept of states.  And what's the point of defin

Open in new window

ing self.prev, self.next, and self.msg, if they don't seem to be used anywhere?
0
HonorGodSoftware EngineerCommented:
I don't understand the context.

To what might prev and next refer?
0
cshore12Author Commented:
I found the use of the 4 arguments in some eMail exception handling code (which I can no longer locate).

The 2.7.2 documentation defines the TransitionError class as follows:

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        prev -- state at beginning of transition
        next -- attempted new state
        msg  -- explanation of why the specific transition is not allowed
    """

    def __init__(self, prev, next, msg):
        self.prev = prev
        self.next = next
        self.msg = msg

I don't really understand how they define the 'states' they're referring to. In my original example, for instance, do they refer to a state where the connection to the eMail server is either off (prev) or on (next)?  If so, how would I define the prev and next arguments?
0
HonorGodSoftware EngineerCommented:
Can you change the order of the parameters to have prev and next occur after msg?

Then you could make prev & next optional...
def __init__( self, msg, prev = None, next = None ) :
    self.msg  = msg
    self.prev = prev
    self.next = next

Open in new window

0
cshore12Author Commented:
Well, I suppose I could.  But that doesn't answer my question -- can you provide examples of what I would pass for 'prev' and 'next'?
0
HonorGodSoftware EngineerCommented:
The values of prev and next would be based upon your application, and how it does things.

If you are familiar with Finite State Machines (FSMs), you should be better to identify the appropriate values of prev and next.

Do you have any examples of the kind of transition that might occur?
0
peprCommented:
For the del and the msg and s... You can also define the msg and s before or at the beginning of the try block like this:
    msg = None
    s = None

Then you possibly redefine the value in the values in the try block.  This way you can be sure that the variables exist even when the exception is raised before assigning them a meaningful value.

Now for the...

    except:
        raise ConnErr(yourPrev, yourNext, yourMsg)

Open in new window


You should think about the prev and next as about any other arguments.  They are not bound to the notion of an exception.  It depends on what your application wants to use them for.  They could be named also arg1, arg2, ... whatever.

It depends on what the code that processes your exception expect.  In Python, there is no type bound to the argument.  This way you can pass whatever as the prev or next if the values are not used late meaningfully.  Often, the None is a good value for the indiferent values.

The TransitionError example in the doc is just the example.  As HonorGod wrote, it seems to be from the finite automata world.

Have a look at http://en.wikipedia.org/wiki/Mealy_machine, see the picture.  The circles with Sx are the states, the s/a at the edges are the symbol/action description.  When you implement such a finite automaton, you may want to know what and where caused the problem.  Basically, the TransitionError class--as shown in the doc--allows you to capture the edge between the states: the state before the error happened as prev, next as state that would occur if the transition did not fail, and message containing the details.  From that point of view, the instance of the TransitionError class would be used as the exception object when the "action" for the edge fails.

It may depend on you how the TransitionError instances be used when the exception is catched.  If you simply want to display some text, then the prev and next and be simply strings to be displayed, or they can be used for rendering the strings to be displayed.


0
cshore12Author Commented:
Thanks, guys, for your excellent feedback.
0
HonorGodSoftware EngineerCommented:
Thanks for the grade & points.

Good luck & have a great day.
0
peprCommented:
... wishing all to have the best year of their life so far ;)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Python

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.