Tech Off Thread

8 posts

other fun stuff about exceptions

Back to Forum: Tech Off
  • User profile image
    ScanIAm

    stevo_ wrote:
    Yes well you are throwing the expection again however.. the last time I checked, that started a new exception, complete with a stack trace from the point of its throw..

    I could be wrong as I've never bothered to recheck my teachings of the past..

    But you want to be:
     
    throw; ing

    not:

    throw ex; ing

    Edit:

    I'd also like to point out you've turned a discussion about the best way to WRITE catching mutliple exception types.. into a debate about how to handle exceptions..

    Your arguments also seem to be against the 'norm' rules of exception catching..

    I'd perhaps employ a similar idea to you during very early testing.. but I would find it very hard to program production code that is to counter-act a bug somewhere else..

    I know it has to happen in some cases, but only when you understand why the bug occurs and how why it is worth counter-acting vs repairing.. even then.. ugh, I'd go home feeling dirty..


    I either slept through class, forgot, or never learned that you could throw the received exception without 're-throwing' it. 

    I shall be immediately fixing this specific code tomorrow Smiley

    I'm interested, though, in how people would handle a situation where the function calls are prone to failures that are outside of your control and, at times, retryable.

    In the case of drivers or other external systems, the goal would be to recover from as many errors as possible and supply the expected result to the caller if at all possible.  It seems, though, that some of you feel that the exception should just happen.  Am I missing something?

  • User profile image
    tgraupmann

    You can also make the rethrown exception more informative by adding a message that gives the exception more context helping you debug later.


    throw new Exception("New message about the problem like I was doing XYZ", ex);

    Just remember exceptions are slow. If you can avoid exceptions by using if statements do it whereever you can.

  • User profile image
    littleguru

    Exceptions should only happen if something goes terribly wrong. For example if you try to open a file that is not there or if you try to access something and you have no rights. That's when they should happen. But you should always be able to check first what you do. Like you can first check if the file is there and open it afterwards. Don't use exceptions for that task: like I'll open and if I get an exception I'll know that the file is not there and I'll do something else as if it would be there.

    Don't use exceptions for flow control!

    I always implement applications in that way: check and do. If an exception happens it will just bubble up. If I'm able to handle it somewhere, because I know exactly what to do with it I'll handle it. For all other exceptions I just register the global exception handling method and print it to a log. The application will crash, yes: but something went wrong in the application and it needs to crash therefore.

    Exceptions aren't anything bad! If you have implemented your application properly you won't run into much anyways. But if one bubbles up it's easy to fix the error - compared to error codes that may have been there and nobody checked for them.

    As said there are exceptions that you handle, because you know exactly how to handle it. But there are exceptions that you can't handle and you shouldn't! How can you handle an OutOfMemoryException or an internal CLRException?



    Offtopic:

    throw new Exception();

    can be translated to:

    Exception ex = new Exception();
    throw ex;


    can be translated to

    Exception ex = new Exception();
    // a lot of other code.
    throw ex;

    that's why throw ex will reinitialize the stack trace. The CLR doesn't understand that you created a new exception. Each time you call it with an exception instance it will just reset the stack trace.


    Edit: you should change the title of the thread to something else... you're no idiot.

  • User profile image
    figuerres

    in the case of an "outside system" sometimes you have no option but to use an ex / try / catch to handle it.

    when you have no clean option then yes; do what you must.

    *BUT*

    if you do then wrap that such that you give the rest of the app or system a "sane world view" so that everyone calls the wrapper and gets normal looking results and hardly ever sees the kluge.

    like return a class with an enum to show status {OK,Err1,Err2,Err3...}
    so that the user of your class can write normal looking code with stuff like if ( foo.Status == Ting.OK)


    also if you have a COM bit to deal with you may need to check some of the old style COM / win32 result stuff to get an error status out of that code before you get to an ex state.

    there is a printer I work with that uses a COM control (really ActiveX for VB is what it is but thats just a detail) it never throws an ex.

    I have to call some code to get a status value and then handle it.

    so just double check how it works, that printer had me doing the wrong thing for a while... till one day I woke up and remembered how I used to havbe to do things with C and DOS!
    now it works much better Smiley

  • User profile image
    ScanIAm

    What figuerres said is the same problem I'm dealing with.  Under controlled situations, like a web page requesting info from the business layer which in turn is requesting data from a database, exceptions are truly unexpected situations, so they shouldn't happen.

    Currently, though, I'm having to deal with some 3rd party software that makes web service calls to another server.  That other server then telnets into a manframe and does some screenscraping to pull of information and return it, eventually, to the web page. 

    The mainframe doesn't allow more than one login per user, so multiple calls cannot be made in parallel.  The mainframe also has the annoying habit of not noticing that one connection has finished, so even though I force my code to manually pause between calls, there are still times when the mainframe thinks that there are 2 live connections from 1 user.  The mainframes response to this situation is to boot both connections off.

    The 3rd party software response to this is to throw an exception and pass it back.  Luckily, I'm able to pass some pertinent info back in that returned exception which I can then check for in my app.  Unfortunately, the only way to see this information is to catch the SoapHeaderException that shows up.

    There are a number of other weird conditions like this, and over time, as I've identified what causes them, I've been able to fix some and work around others. 

    The workaround I came up with was that funky code I listed out.  On the minus side, I've got goofy WTF looking code, but on the plus side, anyone who uses this as a datalayer will likely get the results they were looking for.

  • User profile image
    littleguru

    I might sound like an idiot: but why don't you only handle the SoapHeaderException then? Why all exception types?

    And yes there are situations where you need to catch certain exceptions! But you should only handle the exceptions of which you know exactly what to do with them!

    Also having some kind of Status property that returns the current error is like going back to the error codes! Terrible, really terrible. If you really want to inform the user that a certain problem happend create an exception for it and throw it! Exceptions need to be handled, status codes don't!

  • User profile image
    ScanIAm

    littleguru wrote:
    I might sound like an idiot: but why don't you only handle the SoapHeaderException then? Why all exception types?

    Initially, because I couldn't find any documentation of all the different kinds of exceptions that might occur.  I went ahead and changed it so that now, we only catch the SoapHeaderException.

    I've got an error page for handling unhandled exceptions.  Hopefully we won't receive any un-planned exceptions from the web service.

    littleguru wrote:

    And yes there are situations where you need to catch certain exceptions! But you should only handle the exceptions of which you know exactly what to do with them!

    Also having some kind of Status property that returns the current error is like going back to the error codes! Terrible, really terrible. If you really want to inform the user that a certain problem happend create an exception for it and throw it! Exceptions need to be handled, status codes don't!

    Agreed, but I didn't write the 3rd party app, I just have to use it as best I can.  At least I'm able to pass some kind of information back from the mainframe.  Initially, the exception message would only say something to the effect of "I died on screen XXXX".

    No reason why, just that it died.

  • User profile image
    atehrani

    Far too many times I see incorrect exception rethrowing in C#.


    "Re-throwing" an exception like this is incorrect, as the stack trace will be reset.

    catch ( FooException ex )
    {
           throw ex; // WRONG Sad
    }



    This is the correct way to rethrow an exception.

    catch ( FooException ex )
    {
           throw; // CORRECT Smiley
    }


    Please note that a trace of the stack is only taken when the "throw" keyword is executed. In Java the stack trace is taken when an exception is instantiated. This is a subtle but large difference.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.