• Joon (unregistered)

    HE should have looked at the validation code FIRST!

  • Keko (unregistered)

    I don't want to generate a rant here, but what's wrong with MS developers that they love adding layers and layers of complexity?

  • Hit (unregistered)

    Oh, and just let me add, in order to use sp_OACreate in any code, the calling user has to have System Administrator rights. Which means if the web server is compromised, that account has full access to any function on the sql server.

    Brillant!

  • Tei (unregistered) in reply to Joon
    Joon:
    HE should have looked at the validation code FIRST!

    start with the solution?, you sir, are a genius

  • Jamie (unregistered)

    sp_OACreate makes baby jesus cry.

  • (cs) in reply to Keko
    Keko:
    I don't want to generate a rant here, but what's wrong with MS developers that they love adding layers and layers of complexity?
    Sadly, it's not just MS developers...
  • (cs) in reply to Keko
    Keko:
    I don't want to generate a rant here, but what's wrong with MS developers that they love adding layers and layers of complexity?

    You've got cause and effect the wrong way round there I'm afraid.

  • (cs)

    Of course, Mike could have simply referred to the comprehensive Software Design Documentation and saved himself all that time!

    </sarcasm>
  • Anon (unregistered) in reply to Keko
    Keko:
    I don't want to generate a rant here, but what's wrong with MS developers that they love adding layers and layers of complexity?

    Job security?

  • Mr. Mom (unregistered) in reply to Keko

    It's not MS developers per se. I have run into this sort of hyper-heavy, undocumented garbage "written" by people with various backgrounds (I won't say "competencies"). In my experience as a consultant called in to fix this sort of thing, people who pride themselves on being OO purists are the most likely to find Rube Goldberg ways of exploiting every platform feature (e.g. COM+ in this example) just to say they can, and when hundreds of kLocs get replaced with a fraction as much that passes FxCop, runs faster, exposes one clean simple interface, and has other devs on the team enthusiastically adopt it instead of the old schlock, the facial expressions and self-defending get priceless... KISS and remember, when confronted with lousy code, sometimes forgiveness is easier to get than permission.

  • (cs) in reply to Hit
    Hit:
    Oh, and just let me add, in order to use sp_OACreate in any code, the calling user has to have System Administrator rights. Which means if the web server is compromised, that account has full access to any function on the sql server.

    Brillant!

    Not quite. We use sp_OACreate but if you call it from another stored procedure the user only needs permissions to this stored procedure without giving the user direct access to run sp_OACreate (dangerous). This means that you can easily control user access to the top-level stored procs (using roles) and eveything is hunky-dory and secure. Permission chaining - nice!

  • Bronek (unregistered) in reply to Hit

    IIRC, authorization in SQL Server is derived NOT from executing user, but from owner (of stored proc being executed).

    As to this charming debugging episode, there is old saying: "any programming problem can be solved by another layer of abstraction ... except for too many layers of abstraction"

  • TerryN (unregistered)

    Of course "the application's "let's centralize all error messages and call them only by their three-digit code" phase" may also be more charitably called the application's "prepare for localisation" phase. Not every layer of abstraction is without purpose.

    Tel.

  • Fred (unregistered)

    The worse bugs are the ones that take 6 hours to find and less than 5 keystrokes to fix. Not a WTF, just a normal day.

  • (cs)

    So he moved from "Betrayal of Master" (9th circle of hell) to either "Concern for Material Goods" (4th) or maybe even "Gluttony" (3rd circle).

    Good for him! I'd personally aim for gluttony.

  • Andy (unregistered)

    We are also told that "let's centralize all error messages and call them only by their three-digit code" is a current "best practice". If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.

  • (cs) in reply to Mr. Mom
    Mr. Mom:
    It's not MS developers per se. I have run into this sort of hyper-heavy, undocumented garbage "written" by people with various backgrounds (I won't say "competencies"). In my experience as a consultant called in to fix this sort of thing, people who pride themselves on being OO purists are the most likely to find Rube Goldberg ways of exploiting every platform feature (e.g. COM+ in this example) just to say they can, and when hundreds of kLocs get replaced with a fraction as much that passes FxCop, runs faster, exposes one clean simple interface, and has other devs on the team enthusiastically adopt it instead of the old schlock, the facial expressions and self-defending get priceless... KISS and remember, when confronted with lousy code, sometimes forgiveness is easier to get than permission.

    And when those people find reflection they say to themselves, 'wait, I can write a config file, that contains defenition to create 'an object', and defenition to call 'methods' and the params required for those methods...

    Like you I have to go in sort out messe, the above situation was defended to the death. Apparantly for 'performance' they can 'control' object creation though a centralised framework, and define how objects are accessed via xml.

  • (cs) in reply to Bronek
    Bronek:
    IIRC, authorization in SQL Server is derived NOT from executing user, but from owner (of stored proc being executed).

    nope, it's the executing user.. i created a temp table via enterprise mangler to test, and then ran something that created it via the website and it got all snotty because the table already existed owned by someone else (the sql to delete the table before rebuilding it barfed)

  • Andy (unregistered) in reply to rbowes
    rbowes:
    So he moved from "Betrayal of Master" (9th circle of hell) to either "Concern for Material Goods" (4th) or maybe even "Gluttony" (3rd circle).

    Good for him! I'd personally aim for gluttony.

    Anyone for 2nd circle?

  • willem (unregistered)

    yes, and XSS vulnerable, great!

    "/error.asp?msg=Unable+to+delete%0A+This+sale+has+been+previously+approved."

  • (cs) in reply to ParkinT
    ParkinT:
    Of course, Mike could have simply referred to the comprehensive Software Design Documentation and saved himself all that time!

    </sarcasm>

    [image]

  • (cs)

    Well, I don't know who this Mike is, but I bet Mark was very glad he could pass this problem off to him.

  • Phleabo (unregistered)

    Is the real WTF the fact that it took him 20 minutes to do a full text search over the codebase? I can do a string search over 100 GB of text data in 20 minutes, and that's on a network volume. If his codebase is that large, he's got bigger problems.

    Install cygwin. Learn to use grep.

  • Kooky (unregistered) in reply to Andy
    Andy:
    If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.

    Bad:

    print "LOL You are a fool!! You broke the president!!"
    

    Good:

    if( 'ru' == language ) {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a Дурачок!! You broke the Президент!!"
    } else {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a fool!! You broke the president!!"
    }
    print BROKE_PRESIDENT
    

    Note that my variable name was actually understandable.

    Sheesh, if only more people would read "Code Complete," the world would be a happier place. Strike that. If only people would #@$# read.

  • (cs) in reply to TerryN
    TerryN:
    Of course "the application's "let's centralize all error messages and call them only by their three-digit code" phase" may also be more charitably called the application's "prepare for localisation" phase. Not every layer of abstraction is without purpose.

    Tel.

    Pulling all of your messages out into a resource bundle isn't a bad thing, but this implementation is way out there. First, looks like instead of using a properties file they're stuffing this into a giant switch. Second, I guess it's OK to use 3 character keys (82X or whatever), but the way they are building up the key (first error code 82 then appending some letter) makes it impossible to figure out where that error message is used.

  • steve (unregistered) in reply to Phleabo

    Learn to use grep.

    Glad someone said it. Full-text searches just aren't that hard folks, but the article spins it as if it's something for which you have to schedule server time.

  • (cs) in reply to Kooky
    Kooky:
    Andy:
    If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.
    Bad:
    print "LOL You are a fool!! You broke the president!!"
    
    Good:
    if( 'ru' == language ) {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a Дурачок!! You broke the Президент!!"
    } else {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a fool!! You broke the president!!"
    }
    print BROKE_PRESIDENT
    
    Note that my variable name was actually understandable.

    Sheesh, if only more people would read "Code Complete," the world would be a happier place. Strike that. If only people would #@$# read.

    And this differs from hardcoding text in what way?

  • The real wtf fool (unregistered) in reply to Kooky
    Kooky:
    Good:
    if( 'ru' == language ) {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a Дурачок!! You broke the Президент!!"
    } else {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a fool!! You broke the president!!"
    }
    print BROKE_PRESIDENT
    

    Note that my variable name was actually understandable.

    even if it was mistyped ;-)

    How about this scheme: msg(423, "You broke the moon"); where msg() will look up the translation from a database of languages and IDs. Oh and you must remember not to use the same ID number twice in the same file or the build system barfs. And no there is no automated tool for adding message IDs into a file to make sure they are unique. Another little 'feature' is the recommended process for letting the translators know the message text has changed is to change the ID. I'm sure there are lots of old unused message IDs left in the database...

    These are the joys I face here every day.

  • (cs) in reply to pscs
    pscs:
    Keko:
    I don't want to generate a rant here, but what's wrong with MS developers that they love adding layers and layers of complexity?

    You've got cause and effect the wrong way round there I'm afraid.

    What? Are you suggesting that the layers and layers of complexity create Microsoft developers?

    What a strange mind you have.

  • Ubersoldat (unregistered)

    The Real WTF is that they're using VB... there, I said it, now move on people, nothing to see here.

    Anyway, I can't believe such a level of abstraction is of any good. If this was made onto a diagram or UML it could take me weeks to understand all what this guy is seeing.

    I agree with the later post, "Code Complete" should be a necessary read for every programmer, actually, it should be bonded (what?) with every "Learn X in 24 hours".

  • kwerle (unregistered) in reply to Ubersoldat
    Ubersoldat:
    The Real WTF is that they're using VB... there, I said it, now move on people, nothing to see here...

    Thank you for saying it.

    I also gotta say:

    Mark had little choice but to do a full-text through the entire code base. Twenty minutes and several permutations of the error message later...

    It took him 20 minutes to grep the code for that?

  • Duff (unregistered) in reply to savar
    savar:
    What? Are you suggesting that the layers and layers of complexity create Microsoft developers?

    I read it as a claim that people whose natural inclination is towards adding layers of complexity tend to choose to become Microsoft developers.

    Not that it's exclusive to them -- some of the Java I've seen...

  • (cs) in reply to kwerle

    Notice the words "several permutations" He had to run multiple searchs to narrow down where it was, a lot of the words in the error message probably cropped up in every single file and appeared in all kinds of unrelated error messages.

    This sounds like a suitibly enterprisy enough of a solution with the added feature of perpetual consultant opportunities.

  • J (unregistered) in reply to kwerle

    The whole MS/VB stereotype has been run into the ground, but that doesn't mean it's not true. I worked with a VB developer whose mantra was "n-tier". People thought she was some kind of prodigy who understood the deep complexities of code better than anyone else. I was just starting out, so when I had to plow through layer after layer of business logic and stored procedures to track down where an error message was being thrown, I figured the code was just far more "modular" than I could understand.

    Years later, it turns out the developer either didn't understand or didn't trust the concept of "exception bubbling", but she sure understood the concept of "job security".

  • (cs) in reply to Ubersoldat
    Ubersoldat:
    The Real WTF is that they're using VB... there, I said it, now move on people, nothing to see here.

    Anyway, I can't believe such a level of abstraction is of any good. If this was made onto a diagram or UML it could take me weeks to understand all what this guy is seeing.

    I agree with the later post, "Code Complete" should be a necessary read for every programmer, actually, it should be bonded (what?) with every "Learn X in 24 hours".

    ... or "Forget X in 24 hours," where X = "VB".

    That would be quite a popular book round these parts.

  • Anonymous (unregistered)

    I think they should add a print-to-photograph-to-print-to-scan-to-OCR somewhere in the middle of the process. And a woodden table too.

  • Harrow (unregistered) in reply to Kooky
    Kooky:
    Bad:
    print "LOL You are a fool!! You broke the president!!"
    
    Good:
    if( 'ru' == language ) {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a Дурачок!! You broke the Президент!!"
    } else {
      BROKE_PRESIDENT_MESSAGE = "LOL You are a fool!! You broke the president!!"
    }
    print BROKE_PRESIDENT
    
    Note that my variable name was actually understandable.
    Understandable, maybe, but apparently not very memorable. Your code won't work (unless what you really want to do is assign a string to BROKE_PRESIDENT_MESSAGE here for later use, and then print the contents of BROKE_PRESIDENT previously assigned elsewhere).

    I am going to use this snippet in my course material as another illustration of how every added abstraction layer not only introduces more processing load, but worse, additional opportunities for implementation errors.

    -Harrow.

  • jkupski (unregistered)

    Appropriate title for this story--for there is no doubt that "Mark C." is "a man of constant sorrow."

  • SkittlesAreYum (unregistered) in reply to Andy
    Andy:
    We are also told that "let's centralize all error messages and call them only by their three-digit code" is a current "best practice". If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.

    Well, if you want any sort of localization to work, then it is a bad idea to have text hard-coded, although it has nothing to do with OO.

    The project I'm working on seems to deal with it pretty well. They have a function you can call, StringRetriever::RetrieveString(<string enum goes here>), and that will return your string for you. There's a list of string enumerations that you can use. My experience in this area is limited, but this works very well, at least for a project our size.

  • Leo (unregistered)

    Bah. There's a very simple way to i18n your apps. Instead of message localization just write your app in English, as God Intended.

    And then pipe the app's output through an automated translator. Like, for instance, jive. Or valspeak.

    Simply changing the filter will have your single code base speaking fluent Klingon, or Mock Sweedish.

    It's what I would do. For great justice.

  • c0d3monk33 (unregistered) in reply to Hit

    Seems a lot of WTF involves sh1tty Visual Basic code...hmm, I guess that's a tautology isn't it?

  • BJ Upton (unregistered)

    Wow, but I've seen so much of that sort of thing here.

    CAPTCHA: eros...hahaha

  • (cs) in reply to Grovesy
    Grovesy:
    And when those people find reflection they say to themselves, 'wait, I can write a config file, that contains defenition to create 'an object', and defenition to call 'methods' and the params required for those methods...

    Like you I have to go in sort out messe, the above situation was defended to the death. Apparantly for 'performance' they can 'control' object creation though a centralised framework, and define how objects are accessed via xml.

    It's called "Dependency Injection" and currently considered Teh Awesome by certain OO buzzword chasers.

  • Kyle Bennett (unregistered)

    Should the person named in this article be "Mark the 100th"?

  • ChiefCrazyTalk (unregistered)

    The real WTF is....actually, I don't see a WTF at all. Sounds like a typical day for a typical developer.

  • (cs) in reply to Bounce
    Bounce:
    Hit:
    Oh, and just let me add, in order to use sp_OACreate in any code, the calling user has to have System Administrator rights. Which means if the web server is compromised, that account has full access to any function on the sql server.

    Brillant!

    Not quite. We use sp_OACreate but if you call it from another stored procedure the user only needs permissions to this stored procedure without giving the user direct access to run sp_OACreate (dangerous). This means that you can easily control user access to the top-level stored procs (using roles) and eveything is hunky-dory and secure. Permission chaining - nice!

    Erm.. assigning roles to stored procedures? Maybe you call it nice, I call it a "maintenance nightmare" for the DBAs.

  • dkf (unregistered) in reply to Andy
    Andy:
    We are also told that "let's centralize all error messages and call them only by their three-digit code" is a current "best practice". If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.
    What we do is use English strings but feed those through a "localizer" step that looks up the equivalent in a translation DB. An efficient string-to-string map's trivial to implement (unless you're so far back in the stone age that you've still not got a hashtable implementation) and it's far easier to get it right when you're building the localizations. (Magic error codes? Sheesh! That's WTFy all in itself.)
  • (cs)

    At least he was in the right place to replace the error module with a table in the database.

  • (cs) in reply to Phleabo
    Phleabo:
    Is the real WTF the fact that it took him 20 minutes to do a full text search over the codebase? I can do a string search over 100 GB of text data in 20 minutes, and that's on a network volume. If his codebase is that large, he's got bigger problems.

    Install cygwin. Learn to use grep.

    I assumed he was using SSDS

  • (cs) in reply to SkittlesAreYum
    SkittlesAreYum:
    Andy:
    We are also told that "let's centralize all error messages and call them only by their three-digit code" is a current "best practice". If you have any text hard coded anywhere then you are a poor developer, bad person and just don't understand OO.

    Well, if you want any sort of localization to work, then it is a bad idea to have text hard-coded, although it has nothing to do with OO.

    The project I'm working on seems to deal with it pretty well. They have a function you can call, StringRetriever::RetrieveString(<string enum goes here>), and that will return your string for you. There's a list of string enumerations that you can use. My experience in this area is limited, but this works very well, at least for a project our size.

    Well, the best model I've seen (and it came about by accident, since the thing was written in English and only I18N-ised because of a misguided salesman) was quite simple.

    (1) All messages started life as, well, messages. "Don't do this!", etc. (2) A hasty re-engineering job placed some form of tag (I forget what, but this being Perl, it probably involved one hell of a lot of line-noise) around "Don't do this!" (3) The translation file relevant to the locale was read in at initialisation, such that "Don't do this!"="Laissez cet objet!". (Or whatever.)

    Where a translation existed, it was interpolated as per normal Perl behaviour. Where it didn't, the user got the original English version.

    What the user didn't get was some feeble-minded three-digit magic code, made up of random sub-strings. Let alone the result of an insane recursive call between a series of sql procedures and call-outs to COM.

    But heck, that just wasn't enterprisey enough, was it?

Leave a comment on “O Error, Where Art Thou?”

Log In or post as a guest

Replying to comment #:

« Return to Article