Don't let exceptions ruin your day



  • I've been away from this area of code for about a year, but now I'm back updating a C# utility. When I do a fresh build, I get a dozen or so warnings about un-referenced variables in our core libraries with which we build commercial products.

    I like to build without getting compiler warnings, so I took a look, to discover the warnings are caused by the following:

    try
    {
        // do stuff
    }
    catch (Exception ex)
    {
        ;
    }
    

    This elicited a depressed "fuck me". :(

    Since this is C#, and our app isn't used in life support or fly-by-wire controls, I think we'd really be better off letting the sucker die horribly instead of slogging on, hoping that things work out OK.

    The lead programmer/designer/long-time employee/main author of most of our stuff won't talk to me about it, but I'm pretty sure his attitude is that this shit will never happen, no one using our products has complained, he has lots of real work to do, so STFU.



  • I feel your pain. I see dozens of these on a daily basis.



  • @rstinejr said:

    this shit will never happen, no one using our products has complained

    There is something to be said for that attitude. If the code has been in production for a while, and has not crashed, then it is likely that the try/catch is simply not needed here. BUT if you start modifying code, that means you have to retest it; and (statistically) you have about a 1-in-7 chance of introducing a new bug while "fixing" the old code. Maybe you won't be happy, but its better than being the guy who introduced a bug, however good your intentions were.


    I say the same thing about unit tests -- when you're modifying code, that is a good time to write unit tests for the code you're going to be modifying. There is really no point in writing unit tests for code already running in the field -- if it's running, it is probably working, and your time is better spent writing new code (and unit tests along with the new code).



  • @DrPepper said:


    I say the same thing about unit tests -- when you're modifying code, that is a good time to write unit tests for the code you're going to be modifying. There is really no point in writing unit tests for code already running in the field -- if it's running, it is probably working, and your time is better spent writing new code (and unit tests along with the new code).


    You are bad and should feel bad. Unit tests on already working code is useful because it documents the fact that the code works. The idea is that when you modify a piece of code with unforeseen and unexpected side-effects on another piece of code, having a unit test will catch the breaking of the code that you assumed would be working correctly. This makes things much easier to debug because you don't have to wait until some user runs into the broken code 3 months down the line and then have to spend forever trying to figure out why it broke.



  • I also feel your pain. 

    If this is working code, just add a log to the catchblock and move on, don't dwell on it.

    Once you've had logging in the catchblock in production for a while, then you'll know what to do about this.  

     

    As far as the asshats who are currently creating (or defending) code like this in your organization, do not argue with them (which would reinvent the wheel), just point them to stack overflow's discussion of java exception handling best practices.  While they're busy reading that, you'll have a few minutes to go change their shite code by adding logs to catchblocks!



  • @Snooder said:

    @DrPepper said:



    I say the same thing about unit tests -- when you're modifying code, that is a good time to write unit tests for the code you're going to be modifying. There is really no point in writing unit tests for code already running in the field -- if it's running, it is probably working, and your time is better spent writing new code (and unit tests along with the new code).


    You are bad and should feel bad. Unit tests on already working code is useful because it documents the fact that the code works. The idea is that when you modify a piece of code with unforeseen and unexpected side-effects on another piece of code, having a unit test will catch the breaking of the code that you assumed would be working correctly. This makes things much easier to debug because you don't have to wait until some user runs into the broken code 3 months down the line and then have to spend forever trying to figure out why it broke.

    AKA "regression testing", which is the primary reason to have unit tests in the first place. From his comment, I'm not sure DrPepper understands the point of unit testing at all.



  • @morbiuswilters said:

    @Snooder said:

    @DrPepper said:



    I say the same thing about unit tests -- when you're modifying code, that is a good time to write unit tests for the code you're going to be modifying. There is really no point in writing unit tests for code already running in the field -- if it's running, it is probably working, and your time is better spent writing new code (and unit tests along with the new code).


    You are bad and should feel bad. Unit tests on already working code is useful because it documents the fact that the code works. The idea is that when you modify a piece of code with unforeseen and unexpected side-effects on another piece of code, having a unit test will catch the breaking of the code that you assumed would be working correctly. This makes things much easier to debug because you don't have to wait until some user runs into the broken code 3 months down the line and then have to spend forever trying to figure out why it broke.

    AKA "regression testing", which is the primary reason to have unit tests in the first place. From his comment, I'm not sure DrPepper understands the point of unit testing at all.

    I disagree. Unit tests are not convenient for system-wide modifications; you need integration tests for that. So if you inherit a code base that has not unit tests, time is better spent grouping things in modules based on what interfaces what, and build integration tests for those. In the end it does not matter if some utility class in the ShoppingCart namespace works with bound values or not; what matter is that things that talk to the ShoppingCart will not break or corrupt business logic when you change something on either side.



    Unit tests are mostly a build thing; they are great for a gated check-ins or to move things from one column to the other in a kanban but that's not a reason to go back and inject some if the previous people did not bother writing them.



  • @Ronald said:

    I disagree.

    Well that makes you wrong. I would have thought you'd have this figured out by now..

    @Ronald said:

    Unit tests are not convenient for system-wide modifications; you need integration tests for that.

    I don't even.. I didn't say you don't need integration tests, I said that unit tests are good for catching bugs.

    @Ronald said:

    In the end it does not matter if some utility class in the ShoppingCart namespace works with bound values or not; what matter is that things that talk to the ShoppingCart will not break or corrupt business logic when you change something on either side.

    Both matter. Obviously you do your testing where it will do the most good, but that doesn't mean you avoid unit testing. You unit test complex pieces that are likely to experience bugs or in places where you are likely to catch regressions. It's not that complicated.



  • @morbiuswilters said:

    You unit test complex pieces that are likely to experience bugs or in places where you are likely to catch regressions.

    On new code and on code you modify, yes. On a code base that has not changed in a while, it's a waste of money (unless ideology is a valued cost center in your organization). It's like doing an autopsy on a corpse that apparently died of natural cause, that nobody cares about and that is not the subject of a police investigation. Quincy ME has better things to do.






    This guy has better things to do.


  • Discourse touched me in a no-no place

    @Ronald said:

    On a code base that has not changed in a while, [writing unit tests is] a waste of money (unless ideology is a valued cost center in your organization).
    I hear what you say and respectfully disagree. Maybe you don't work with developers who think that changing the definition of equality on a class is a good idea (“to speed things up” <sigh>) but recording what should work and what should fail are very useful for ensuring that maintenance stays on the straight-and-narrow.



  • @dkf said:

    @Ronald said:
    On a code base that has not changed in a while, [writing unit tests is] a waste of money (unless ideology is a valued cost center in your organization).
    I hear what you say and respectfully disagree. Maybe you don't work with developers who think that changing the definition of equality on a class is a good idea (“to speed things up” <sigh>) but recording what should work and what should fail are very useful for ensuring that maintenance stays on the straight-and-narrow.

    I guess it depends on the type and size of the project. If my company was building a single product, I could see the value in that. But if it's a big company which has a huge messy pile of half-COTS, half-in-house solutions, it's a constantly changing landscape and you only need to record interactions.



    As a general rule in big organizations I don't think that unit testing is very high on the radar. I believe in BDD where the purpose of unit tests is to determine if a specifications is met. In that context, code that does not change is by definition meeting the requirements and does not justify labor unless there is a change request. Again in a small shop things may be different.



  • @Ronald said:

    In that context, code that does not change is by definition meeting the requirements and does not justify labor unless there is a change request.

    But you seem to be under the impression that that code might not find some new use, which would trigger broken behavior. Or that code it depends on won't change and trigger some bug. No piece of code is an island.


  • Discourse touched me in a no-no place

    @rstinejr said:

    I've been away from this area of code for about a year, but now I'm back updating a C# utility. When I do a fresh build, I get a dozen or so warnings about un-referenced variables in our core libraries with which we build commercial products.

    I like to build without getting compiler warnings, so I took a look, to discover the warnings are caused by the following:

    try
    {
        // do stuff
    }
    catch (Exception ex)
    {
        ;
    }
    

    This elicited a depressed "fuck me". :(

    Since this is C#, and our app isn't used in life support or fly-by-wire controls, I think we'd really be better off letting the sucker die horribly instead of slogging on, hoping that things work out OK.

    The lead programmer/designer/long-time employee/main author of most of our stuff won't talk to me about it, but I'm pretty sure his attitude is that this shit will never happen, no one using our products has complained, he has lots of real work to do, so STFU.

    This actually makes me glad I DON'T work in a place with a language that has newfangled constructs like exceptions, although to be fair to my coworkers, none of them would pull that shit.



  • @morbiuswilters said:

    @Ronald said:
    In that context, code that does not change is by definition meeting the requirements and does not justify labor unless there is a change request.

    But you seem to be under the impression that that code might not find some new use, which would trigger broken behavior. Or that code it depends on won't change and trigger some bug. No piece of code is an island.

    Here is the Ronald Formula for Enterprise Architecture: "BUY > REWRITE > REUSE". Here is the derived Ronald Law of Enterprise Architecture: "Given any large organization, code reuse will always end up biting you in the ass. Fuck that."



    Again in smaller organizations the thinking may be different, but don't let that dichotomy get in the way of a universal ideology. We all know developers love their libraries.



  • @theflin said:

    I feel your pain. I see dozens of these on a daily basis.

    Ah, another outsource-virgin, I presume.

    In one codebase I got (PHP), I estimated the number of this construct in the high thousands. In typical cargo-cult fashion, the overwhelming majority were wrapping functions or trivial constructs which could not generate exceptions at all.

    And then, I found this—

    try
    {
    	if(!$reslut)
    	{
    		throw new Exception('001','');
    	}
    }
    catch(Exception $e)
    {
    	throw $e;
    }
    

     No, not edited at all, other than to correct indentation.



  • @SamC said:

    try
    {
    if(!$reslut)
    {
    throw new Exception('001','');
    }
    }
    catch(Exception $e)
    {
    throw $e;
    }

    I know I always double-throw an exception when a girl won't reslut.


  • Discourse touched me in a no-no place

    @_leonardo_ said:

    just point them to stack overflow's discussion of java exception handling best practices
    Like this one?@SO said:
    closed as not constructive by [5 different people]



  • @PJH said:

    @_leonardo_ said:
    just point them to stack overflow's discussion of java exception handling best practices
    Like this one?@SO said:
    closed as not constructive by [5 different people]

    Goddammit Stack Overflow..

    The saddest part is the comments section of the only answer.. there's apparently some argument over whether you should write your own exception types or just throw the built-in ones everywhere, which is something so stupid I didn't even know people argued about it. The people against using your own exceptions apparently feel it is too wasteful of resources, so a guy who actually knows something about the JVM slaps them down:

    @Guy who actually knows something about the JVM said:

    throwing an exception is more costly than an if, but it isn't such a performance hog. Negligible compared to any inter-process call or IO operation. First do it right, then optimize only if necessary, and if you've measured that this was the cause of the performance problem. It won't be.

    Which receives this nitwit reply:

    @Tom 'Retard' Andersone said:

    200% of a few instructions is still a few instructions.

    So there ya have it, folks: user-defined exceptions are too expensive for modern computers. Pass it on!

    Figuring that this Tom moron had to be a treasure trove of valuable WTFs, I went to his profile and the clicked on the first answer I saw: http://stackoverflow.com/questions/17568167/eliminate-magic-number/17568276#17568276

    Basically, a guy is trying to get rid of a magic (but arbitrarily-chosen) number in the following line:

    'score' => 1000 - string.size

    Our Hero Tom answers as such:

    @An Idiot said:

    Does the score have to be positive? If not:

    'score' => -string.size

    Essentially, this is replacing 1000 with 0. 0 is one of the numbers that you're allowed to use without it being considered magic!

    Now, I dunno, maybe he was trying to be cute here, but this is really stupid. First off, an unexplained zero is just as much of a magic number as any other. What's more, he's completely fucking missed the point of avoiding magic numbers, and simply come up with a clumsy workaround that is just as opaque as the first example. And people wonder why I have no faith in this fucking industry.


  • ♿ (Parody)

    @morbiuswilters said:

    @Guy who actually knows something about the JVM said:
    throwing an exception is more costly than an if, but it isn't such a performance hog. Negligible compared to any inter-process call or IO operation. First do it right, then optimize only if necessary, and if you've measured that this was the cause of the performance problem. It won't be.

    Which receives this nitwit reply:

    @Tom 'Retard' Andersone said:

    200% of a few instructions is still a few instructions.

    So there ya have it, folks: user-defined exceptions are too expensive for modern computers. Pass it on!

    Hmm...I read the 200% bit as agreeing with the other guy. Or maybe reinforcing. Possibly if I saw more context, I'd agree with you, but I'm not going there.

    I've found stackoverflow to be very helpful, but not with this sort of thing. Usually I'm trying to find the magic place in some configuration xml file, or find the magic API to touch to work around something or other that I don't really understand because I've never had to deal with it before. The problems and solutions are usually subtly different than my situation, but it gets me headed down the right path, or at least gives me better targeted search terms.



  • @PJH said:

    Like this one?

    I love how insane the first link in the opening post is; "Best Practices for Exception Handling".
    First it says you should use unchecked exceptions if calling code is unlikely to be able to handle the exception, and checked exceptions if it probably can.
    Then it says if you aren't putting any extra fields in there, you should just use a standard Exception or RuntimeException, ignoring the fact that if you try to catch an Exception you also catch all RuntimeExceptions.



  • @PJH said:

    @_leonardo_ said:
    just point them to stack overflow's discussion of java exception handling best practices
    Like this one?@SO said:
    closed as not constructive by [5 different people]
     

    uhh, yah, not so good i suppose.  I thought I had looked up some info there to convince some coworkers earlier last year, but it must have been from places like these:

    http://c2.com/cgi/wiki?ExceptionPatterns

    http://javarevisited.blogspot.com/2013/03/0-exception-handling-best-practices-in-Java-Programming.html

    https://today.java.net/article/2006/04/04/exception-handling-antipatterns

     

    Finding specific Patterns and Anit-patterns is a great way to make sense of things while shifting from fighting your coworker's stance ("it'll never happen"), to fixing things in the code, which saves time arguing.  

    It depersonalizes the issue... it's not "your code", it's a "pattern" which arose in "the code", and we can fix a pattern that has gone awry.



  • @boomzilla said:

    Hmm...I read the 200% bit as agreeing with the other guy.

    Shit, maybe you're right.

    Still, he did say that asinine thing about magic numbers, so I hate him and hope he gets raped by a bear.


  • ♿ (Parody)

    @morbiuswilters said:

    @boomzilla said:
    Hmm...I read the 200% bit as agreeing with the other guy.

    Shit, maybe you're right.

    Still, he did say that asinine thing about magic numbers, so I hate him and hope he gets raped by a bear.

    I can live with that.



  • It's stories like this that make me feel justified in my <insert adjective indicating your flavor of disagreement here> assertion that software exceptions cause more problems than they solve.



  • @too_many_usernames said:

    It's stories like this that make me feel justified in my <insert adjective indicating your flavor of disagreement here> assertion that software exceptions cause more problems than they solve.
    I gather you think assertions cause fewer problems than exceptions.

     



  • Yes, because as we all know the following are impossible given the function

     

    HRESULT DoSomething() {...}

     

    void UseDoSomething()

    {

       DoSomething();

    }

     

    void UseDoSomething2()

    {

       HRESULT hr = DoSomething();

    }



  • @Sutherlands said:

    Yes, because as we all know the following are impossible given the function

     

    HRESULT DoSomething() {...}

     

    void UseDoSomething()

    {

       DoSomething();

    }

     

    void UseDoSomething2()

    {

       HRESULT hr = DoSomething();

    }

    Variable declaration as the last statement in a block? That should be a syntax error in any sane language, and a semantic error in every slightly-less-but-still-acceptibly-sane language.



  •  @Ben L. said:

    Variable declaration as the last statement in a block? That should be a syntax error in any sane language, and a semantic error in every slightly-less-but-still-acceptibly-sane language.

    You realize the OP had

    1) a variable declaration with no access (ex)

    2) a statement that was only a semicolon

     

    You think warnings are going to stop them?

     

    edit: and just for the record, there was nothing "wrong" with the first statement...



  • @Ben L. said:

    @Sutherlands said:

    Yes, because as we all know the following are impossible given the function

     

    HRESULT DoSomething() {...}

     

    void UseDoSomething()

    {

       DoSomething();

    }

     

    void UseDoSomething2()

    {

       HRESULT hr = DoSomething();

    }

    Variable declaration as the last statement in a block? That should be a syntax error in any sane language, and a semantic error in every slightly-less-but-still-acceptibly-sane language.

    If you make every silly thing a syntax error, then nobody would ever finish writing a compiler.



  • @immibis said:

    If you make every silly thing a syntax error, then nobody would ever finish writing a compiler.

    Ben has a really twisted view of how a compiler should work, which comes from Go. For example, he believes all warnings should halt the compiler.



  • @morbiuswilters said:

    @immibis said:
    If you make every silly thing a syntax error, then nobody would ever finish writing a compiler.

    Ben has a really twisted view of how a compiler should work, which comes from Go. For example, he believes all warnings should halt the compiler.


    But then they wouldn't be warnings D:


Log in to reply