• Omego2K (unregistered) in reply to Gibbon1
    Gibbon1:
    XXXXXX:
    Like all great exception reporters, he discarded the stack trace and only showed the message.

    Thumbs Up Man!

    I usually just spit the entire thing out in a message box. Everyone says that's a horrible unprofessional thing to do. Except the users who never complain about it. They just take a screen shot and email it to me. Fifteen lines of soup at least appears more helpful than 'FILE_NOT_FOUND'

    I have one application cough Cadence cough Allegro cough PCB Designer cough. It spits out error numbers when things go wrong. Ask support for a list of error codes and what they mean and they'll admit there is no such list. And since it's just a number, they can't help.

    Your users send you a screen shot? Could that be a clue you're doing it wrong?

  • (cs) in reply to mrputter
    mrputter:
    lscharen:
    Another refactor to prevent Kuli and MiffTheFox from exploding your stack... <snip>

    Sorry, dude. Unsolvability of the halting problem says you can't win that arms race.

    <snip>

    Ok, one more try... ;)

    catch (Exception ex) {
        var visited = new HashSet<Exception>();
        var maxDepth = 10;
        while (ex != null && !visited.Contains(ex) && maxDepth > 0)
        {
            visited.Add(ex);
            maxDepth -= 1;
    
            MessageBox.Show(ex.Message);
            ex = ex.InnerException;
        }
    
        if (maxDepth <= 0)
        {
            throw new Exception("Malicious Exception detected.  WTF!!!!");
        }
    }
    
  • EsotericNonsense (unregistered) in reply to Spewin Coffee

    This is why exceptions were invented. So you don't have to create a fancy data type just to handle error messages in your program. They actually work pretty good if you use them right. The fact that exceptions are often badly used is not the fault of the construct it's self.

  • (cs) in reply to EsotericNonsense
    James:
    right because

    int myFunc(char parm1, int parm2, object* returnValue);

    is totally impossible to do in C/C++. Where object is of whatever type you want to get back; and the int returned by myFunc is either a Boolean or some error error code value. It works almost the same in Java. Strict typing has nothing to do with it.

    The bigger issue comes when you have have to now check all those error results in your code path. If your next action is already conditional your error handling response is any more complex than

    if !(myfunc(...)) {exit(1);}

    the decision trees get pretty large. Have fun debugging that. Exceptions are useful when used well. That fact that most people don't use them well is not a problem with the syntax or language facility; its a problem with you, me, and anyone else who writes sloppy code out there.

    Maybe something like:

    public DataTable GetCompanies(out bool success) {
       if(success) {
          // proceed as normal
       } else {
          // something went wrong
       }
    }
    
    Omego2K:
    Your users send you a screen shot? Could that be a clue you're doing it wrong?

    What, you don't like Outlook as an Error Log? :)

    EsotericNonsense:
    This is why exceptions were invented. So you don't have to create a fancy data type just to handle error messages in your program. They actually work pretty good if you use them right. The fact that exceptions are often badly used is not the fault of the construct it's self.

    Exactly.

  • Mike (unregistered) in reply to snoofle

    No there are not, but that is ok, because the exception of no more exceptions will be caught.

  • Ryan (unregistered) in reply to LazerFX

    Close, but here's a small refinement...

    catch (Exception ex) {
      while (ex != null) {
        MessageBox.Show(ex.Message);
        ex = ex.InnerException;
      }
    }
    
  • (cs) in reply to EsotericNonsense
    EsotericNonsense:
    This is why exceptions were invented. So you don't have to create a fancy data type just to handle error messages in your program. They actually work pretty good if you use them right. The fact that exceptions are often badly used is not the fault of the construct it's self.
    Exceptionally WRONG!

    Exceptions are basically a way to circumvent static type checking.

    A function that declares "returns Cake" states that it only ever will return Cake (or null, if you are using one of those billion-dollar-mistake-programming-languages, which Haskell is not part of. Yes you read that right: No null in Haskell!).

    However in programming languages with Exceptions, the function may actually return a Cake, or throw an Exception.

    The "returns Cake" is a lie!

    Which Exception may it return? Well C++ allows even to throw any Object, so the return type of your program has become "returns Mail or any Object".

    And when an Exception is thrown, it is unclear where it will be processed. It might be not processed at all, just ending the program.

    So you lose static type safety and any predictability with Exceptions.

    The Either-Monad, as shown in two other posts before, does not only exist in the functional programming language Haskell and the functional-OO-hybrid Scala (both statically type-checked), but can be also implemented in regular Java.

    (You want that Either-Type only have two subclasses: Left and Right. You can do this by giving Either a private constructor and put the Left- and Right-implementations in the same file as Either).

    However the absence of Lambdas in pre-JDK1.8-Java makes it more awkward to use.

  • jay (unregistered) in reply to keigezellig
    keigezellig:
    TRWTF is the empty catch block. What if the call to MessageBox.Show() fails? (maybe because of the too much nesting :-) )

    I think the try/catch is needed because askking for the inner exception when you've already reached the innermost one returns a null, so when you try to go yet another level you throw a null-pointer exception. So they have to catch that and discard it. This is a programming technique called "lazy and lame".

  • jay (unregistered)

    "Each exception thrown by our application must be caught handled before the user sees it." Except then it pops up a message box to display the error, which, I would think, means that "the user sees it".

    Well, I suppose you did catch the message before the user sees it. You caught the message, and then promptly displayed it for the user. Thus you caught it before the user saw it. Requirement met. I've got to remember that technique. And remember to question what the word "is" means.

    captcha: appellatio. I'm not sure what it means but I think it's something obscene.

  • Jimmi (unregistered)

    Exception.ToString() perhaps?

  • Jimmi (unregistered) in reply to MiffTheFox

    Nice one :D

  • Oh the pain! (unregistered) in reply to Smouch
    Smouch:
    The real WTF is using anything other than Exception.ToString()

    Who cares what the exception message is, normally it's wrong/misleading/empty anyway. What you need is a stack trace, which is what ToString generates for you.

    <rant>

    This. If I had a cent for every "developer" printing/logging ex.Message, and not printing ex.ToString() anywhere, I would be filthy rich.

    And don't get me started with the "that is too ugly for my users, just output ex.Message!!!" folks. Hopeless. Idiots. </rant>

  • Jimmi (unregistered) in reply to Will
    Will:
    Dipshits.

    Exception.ToString() already does this for you.

    Throw this in LinqPad, then stop making fun of stupid people when you're just as fucking dumb.

    new Exception("You", new Exception("Are", new Exception("Fucking", new Exception("Stupid")))).ToString()

    Beat me to it :)

  • (cs) in reply to no laughing matter
    no laughing matter:
    EsotericNonsense:
    This is why exceptions were invented. So you don't have to create a fancy data type just to handle error messages in your program. They actually work pretty good if you use them right. The fact that exceptions are often badly used is not the fault of the construct it's self.
    Exceptionally WRONG!

    Exceptions are basically a way to circumvent static type checking.

    A function that declares "returns Cake" states that it only ever will return Cake (or null, if you are using one of those billion-dollar-mistake-programming-languages, which Haskell is not part of. Yes you read that right: No null in Haskell!).

    However in programming languages with Exceptions, the function may actually return a Cake, or throw an Exception.

    The "returns Cake" is a lie!

    Which Exception may it return? Well C++ allows even to throw any Object, so the return type of your program has become "returns Mail or any Object".

    And when an Exception is thrown, it is unclear where it will be processed. It might be not processed at all, just ending the program.

    So you lose static type safety and any predictability with Exceptions.

    The Either-Monad, as shown in two other posts before, does not only exist in the functional programming language Haskell and the functional-OO-hybrid Scala (both statically type-checked), but can be also implemented in regular Java.

    (You want that Either-Type only have two subclasses: Left and Right. You can do this by giving Either a private constructor and put the Left- and Right-implementations in the same file as Either).

    However the absence of Lambdas in pre-JDK1.8-Java makes it more awkward to use.

    I disagree. If the function executes without an exception, the caller then moves on to the next statement. If there is an exception, that propagates up the stack, and the caller has to handle it, or it continues going up the stack.

    Saying that a function "returns an exception" is inaccurate. It may generate one, but not return one.

    However, I do agree with what you said about where an exception is processed. It's just part of the scope of the code. It keeps going up until it is processed. Whether it's by the app that generated the exception, or by the environment that it's running in, something went wrong, and needs to be addressed somewhere.

  • Captain Oblivious (unregistered) in reply to Spewin Coffee
    Spewin Coffee:
    Ugh. Exceptions. The out-of-band method of returning a sensible error state wrapped up in so-called "modern programming". Try-catch is rife with pointless issues. The only good thing try-catch can do is automatically restart a program that's crashed.

    A more rational approach is to return a structure from all calls that contains a boolean to indicate success or failure of the call. If successful, the data portion contains the returned data. On failure, the data portion contains a human-readable error message, a machine-friendly error code, and optional data. The programmer is first required to unwrap the result of the call and test for success/failure, which should always be done, but no one does. If the return type enforces checking, the programmer will check it. try-catch doesn't enforce checking - programmers just let exceptions bubble up and they log the error(s) at best.

    But the only languages that can handle that sort of return policy natively are weakly-typed languages (e.g. PHP can implement it via arrays). Strongly-typed languages, usually the sort that require an intermediate compilation stage, have a more difficult time (e.g. C++ could process the return data via macros but it would turn into a complete disaster pretty quickly).

    It sounds like you're looking for Haskell.

  • Exceptions checked here (unregistered) in reply to chubertdev
    chubertdev:
    no laughing matter:
    EsotericNonsense:
    This is why exceptions were invented. So you don't have to create a fancy data type just to handle error messages in your program. They actually work pretty good if you use them right. The fact that exceptions are often badly used is not the fault of the construct it's self.
    Exceptionally WRONG!

    Exceptions are basically a way to circumvent static type checking.

    A function that declares "returns Cake" states that it only ever will return Cake (or null, if you are using one of those billion-dollar-mistake-programming-languages, which Haskell is not part of. Yes you read that right: No null in Haskell!).

    However in programming languages with Exceptions, the function may actually return a Cake, or throw an Exception.

    The "returns Cake" is a lie!

    Which Exception may it return? Well C++ allows even to throw any Object, so the return type of your program has become "returns Mail or any Object".

    And when an Exception is thrown, it is unclear where it will be processed. It might be not processed at all, just ending the program.

    So you lose static type safety and any predictability with Exceptions.

    The Either-Monad, as shown in two other posts before, does not only exist in the functional programming language Haskell and the functional-OO-hybrid Scala (both statically type-checked), but can be also implemented in regular Java.

    (You want that Either-Type only have two subclasses: Left and Right. You can do this by giving Either a private constructor and put the Left- and Right-implementations in the same file as Either).

    However the absence of Lambdas in pre-JDK1.8-Java makes it more awkward to use.

    I disagree. If the function executes without an exception, the caller then moves on to the next statement. If there is an exception, that propagates up the stack, and the caller has to handle it, or it continues going up the stack.

    Saying that a function "returns an exception" is inaccurate. It may generate one, but not return one.

    However, I do agree with what you said about where an exception is processed. It's just part of the scope of the code. It keeps going up until it is processed. Whether it's by the app that generated the exception, or by the environment that it's running in, something went wrong, and needs to be addressed somewhere.

    This. Also, how do you lose predictability? In any exception-having language I've seen, every single possible exception at any point has a very predictable path. Either it's caught or it's sent up the stack.

  • AN AMAZING CODER (unregistered)

    Are glaring grammar errors in the featured articles a meme?

  • (cs) in reply to LazerFX
    LazerFX:
    Well, TRWTF is this method of catching exceptions, but if you really must...
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        while (ex.InnerException != null)
        {
            ex = ex.InnerException;
            MessageBox.Show(ex.Message);
        }
    }

    I believe TRWTF is actually that you would probably be better off just using Exception.GetBaseException() to find the original exception.

  • Dominic (unregistered) in reply to Captain Oblivious
    Captain Oblivious:
    Spewin Coffee:
    Ugh. Exceptions. The out-of-band method of returning a sensible error state wrapped up in so-called "modern programming". Try-catch is rife with pointless issues. The only good thing try-catch can do is automatically restart a program that's crashed.

    A more rational approach is to return a structure from all calls that contains a boolean to indicate success or failure of the call. If successful, the data portion contains the returned data. On failure, the data portion contains a human-readable error message, a machine-friendly error code, and optional data. The programmer is first required to unwrap the result of the call and test for success/failure, which should always be done, but no one does.

    It sounds like you're looking for exceptions.
    ftfy
  • (cs) in reply to hikari
    hikari:
    I believe TRWTF is actually that you would probably be better off just using Exception.GetBaseException() to find the original exception.

    Half the battle in .NET is knowing the framework and what's already done for you.

  • Mike (unregistered)

    Inner piece ... or try to reference a null and die a horrible death like we are trying to avoid by having a generic handler in the first place. Nice.

  • instigator (unregistered) in reply to LazerFX

    Please append the error strings and show only one box.

  • instigator (unregistered) in reply to Exceptions checked here
    EsotericNonsense:
    This. Also, how do you lose predictability? In any exception-having language I've seen, every single possible exception at any point has a very predictable path. Either it's caught or it's sent up the stack.

    It is often non-obvious when a function will throw an exception, particularly in c# which has no checked exceptions, and particularly if the function you are calling calls an exception throwing function without a try catch. Furthermore, not ending the program can be nice in some cases, but in others it makes debugging tricky. Your program just got into a funny state, and you lost the part of the stack that caused to problem.

  • instigator (unregistered) in reply to Will

    Yes, their all idiots for not having complete knowledge the .net API. Everyone should know this, even if they are java or c++ programmers.

  • Richard (unregistered) in reply to lscharen
    lscharen:
    Ok, one more try... ;)

    You don't need to call both Contains and Add on the HashSet; Add will return false if the set already contains the value you're trying to add.

    You also don't need to maintain a separate count of the items you've visited.

    And anyone who writes "throw new Exception" should be boiled in a vat of elephant dung; ALWAYS use a more specific exception type!

    catch (OutOfMemoryException)
    {
        // Nothing you can do with this one.
        throw;
    }
    catch (StackOverflowException)
    {
        // Or this one; your code is doomed.
        throw;
    }
    catch (Exception ex) 
    {
        var visited = new HashSet<Exception>(ReferenceEqualityComparer.Instance);
        while (ex != null && visited.Add(ex) && visited.Count < 10)
        {
            MessageBox.Show(ex.Message);
            ex = ex.InnerException;
        }
    
        if (ex != null)
        {
            throw new YorickHuntException("Malicious Exception detected.  WTF!!!!");
        }
    }
    
  • (cs) in reply to Richard
    Richard:
    lscharen:
    Ok, one more try... ;)
    <snip insightful and appropriate corrections...>

    All of which goes to show that writing good and correct code, even for seemingly simple tasks like catching an Exception, is almost always much, much more difficult than anyone initially realizes.

  • RandomAnon (unregistered) in reply to El Fredo

    Well... I guess we now know that an Inception is the deepest INnerexCEPTION posible.

    It all starts with a well placed NullPointerException.

    Tired from luptatum with all these exceptions.

  • Chris (unregistered) in reply to Paul Neumann

    yay for multiple return values.

    http://golang.org/doc/articles/error_handling.html

  • Neil (unregistered)

    The original code lends itself to a recursive implementation:

    private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
    try
    {
    ShowException(e.Message);
    }
    catch { }
    }

    private void ShowException(Exception ex) { MessageBox.Show(ex.Message); ShowException(ex.InnerException); }

    It will usually finish with a null dereference exception unless you throw one of those weird exceptions from earlier comments in which case you'll get a stack overflow or some such.

  • Arancaytar (unregistered)

    So I heard you like Exceptions...

  • APolak (unregistered) in reply to Brian Friesen

    The exception handling code is a major performance bottleneck? I think something went wrong there.

  • Edgar (unregistered) in reply to Spewin Coffee
    <sarcasm> Dude I totally agree. I would much rather read code like this:

    if(!FooA()) goto Error if(!FooB()) goto Error if(!FooC()) goto Error

    return; :Error HandleError();

    or this: if(FooA()) if(FooB()) if(FooC()) return;

    HandleError();

    than to read code like this: try{ FooA(); FooB(); FooC(); } catch(Exception e){ HandleError(e); }

    Not to mention code performs so much better when you're constantly checking for error states. </sarcasm>

  • TZ (unregistered)

    this is sooooo deep.

  • Michael "notriddle" Howell (unregistered) in reply to chubertdev

    For C++, you could use boost::variant http://www.boost.org/doc/libs/1_52_0/doc/html/variant.html. With destructors, you could even require errors to be "defused" to avoid crashing the program. :P

    For Haskell, not only is the Maybe typeclass a possible solution https://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe, it's the preferred one.

    More strongly-typed languages should allow this.

Leave a comment on “Inexception”

Log In or post as a guest

Replying to comment #:

« Return to Article