• brillant (unregistered) in reply to ex-vb6-dev
    Desperate Times
    How many times is desperate? Because that's pretty much how many times the log file will be opened and closed. Unless, of course, you hit an error and you overflow the stack, crashing the program.
  • spike (unregistered) in reply to jspenguin
    jspenguin:
    At least they didn't use 'On Error Resume Next'.

    no but they wrote their own version of it, where they log the error then resume next. this version has the added feature of exploding when the logging function fails.

  • Fred (unregistered)

    The Real WTF is that at the end of the article is a link: "Add Comment"

  • SlightlyAjar (unregistered)

    I confess. I used to comment like that... I kept the indentation the same though, but they were school projects and I was in a hurry and we had no standards!

    It's a tough habit to shake.

  • OldHand (unregistered) in reply to dkf
    dkf:
    Cv:
    Oh that's awesome! I'd love to see that baby go when disk's full or whatever other error (that will be repeated, which is basically any error) in that function occurs.
    That reminds me of one time when I managed to inadvertently fill up the (pitifully small) /var filesystem on an old Solaris workstation, long ago. Things started out as being a little bit unhappy, but quickly got worse as syslog insisted on logging the fact that the filesystem was full and that it couldn't write to the log. For reasons I do not understand entirely, this rendered the whole machine unusable until it was hard rebooted (couldn't do a soft shutdown because that was logged...)

    All this was made worse by the fact that there was no indication at all as to what had caused the problem in the first place. (It was a combination of a strange front end to lpr that was struggling with printing a large document, and the aforementioned tiny filesystem, but it took quite a bit of work to find that out.)

    Years ago we had procmail filling up the disk AND spamming our customer base. The problem was an automated script taking a list of email addresses created on windows, transferring this to a Linux server and converting it to procmail rules. The problem was an empty line, which translated to a procmail rule with empty recipient. This resulted ina loop, sending the same mail over and over again to the whole customer list (about a 1000), and filling up the disk which thankfully stopped the whole thing.

    We sent out an apology, fixed the problem (we thougth) restarted the server... After 17 new copies we were threatened by legal action from one recipient, another one simply said "You better quit while you are ahead"...

  • blah (unregistered)

    Desperate times? This code clearly does disparate times.

  • Hatterson (unregistered) in reply to Christopher
    Christopher:
    Don't forget, the logs for December 5th will be found in the January 25th file.
    Great catch. I missed that.

    Overlapping days would be: Nov 1 through Nov 9 - Jan 11 through Jan 19 Dec 1 through Dec 9 - Jan 21 through Jan 29

  • Pamela (unregistered) in reply to Hatterson

    Can someone explain to me what this is about, and where these date ranges are coming from? My VB6 knowledge is about as good as this code.

  • Ryan (unregistered) in reply to coyo
    coyo:
    amischiefr:
    Hey, at least it's well commented.

    ' add 1 to x x = x + 1

    I'm sorry, a comment like that ads nothing. It's filler, like soy in a hot dog. It's bloated, fills you up and gives you gas.

    The only upside is it makes you look like you're putting in comments.

    I think he probably commented the code before coding it. It's a technique that I use myself, though not (always) to that level. Depends on who's reading the code and how experienced I am at the time (coding or in the language).

    I'd almost certainly comment like that were I to try and code in say python or ruby, as I've never touched either before.

  • (cs) in reply to Pamela
    Pamela:
    Can someone explain to me what this is about, and where these date ranges are coming from? My VB6 knowledge is about as good as this code.

    Using the December 5 - January 25 one as an example:

    December 5 is 12/5 January 25 is 1/25

    The way it's storing the dates, they'll both end up as the string "<year>125_log.txt". Of course this is a bit of an assumption on my part since I've never actually used the VB date functions in question.

  • Tyrathect (unregistered)

    Boy the race condition are really heinous.

    I think it works like this:

    Multiple threads will eventually try to create the same file at the same time. One of these will throw an error, which will call the logging function again. This time, maybe, the file has been created already and the process goes on to log the error that there was an error logging the error.

    After that, execution resumes but the error file was never properly so a new error occurs each time #1 is referenced.

    So, under high load, each sparkly new log file will show a string of io errors at the beginning, and the original log entry will be lost.

  • (cs) in reply to Tyrathect
    Tyrathect:
    Boy the race condition are really heinous.

    I think it works like this:

    Multiple threads will eventually try to create the same file at the same time. One of these will throw an error, which will call the logging function again. This time, maybe, the file has been created already and the process goes on to log the error that there was an error logging the error.

    After that, execution resumes but the error file was never properly so a new error occurs each time #1 is referenced.

    So, under high load, each sparkly new log file will show a string of io errors at the beginning, and the original log entry will be lost.

    Hey /tdwtf/ I need your help My error file was never properly what should I do... is this dangerous ??
  • Dover (unregistered) in reply to Some Philosophy Guru
    Some Philosophy Guru:
    Determinism: The reason you "choose" to believe you have free will.
    [image]
  • Someone (unregistered) in reply to lolwtf
    lolwtf:
    I like the "goto EndSub" instead of "exit sub".

    I want to blame the infinite loop on someone who was copying and pasting that code into everything without paying attention. Given their brillant commenting though, I somehow doubt this.

    Some people are taught that functions should only have one exit point, so they use techniques as the above. In some languages where 'goto' is discouraged these programmers (I might be using the term loosely in some cases) will have a flag on whether an error has occurred and check that every step of the way....

    I have seen lots of

    errorCode = doSomething(someParameters);
    if(errorCode != ALL_OK)
    {
      errorCorde = doSomethingElse(otherParamters);
    }
    if(errorCode != ALL_OK)
    {
      errorCode = tryThisFunction();
    }
    if(errorCode != ALL_OK && errorCode != MOSTLY_OK)
    {
      errorCode = whatAboutThis();
    }
    

    ....etc.... }

  • Kludge (unregistered) in reply to kmarsh
    kmarsh:
    No modern programmer needs to live with bad indentation.

    There are tools available, and have been available for more than a decade, that change the code to something readable, let you edit it, and then if necessary, change it back to the bad indentation pattern, your changes and all, for minimal source base diffs.

    Failure to recognize this just indicates a desire to punish oneself.

    Many people don't bother indenting comments, especially in languages that have a single character comment starter (shell scripts are another where the code is often indented, but not the comment).

    In programs/scripts where every line is not commented, it is actually not always that difficult to follow the code.

  • Anon. (unregistered)

    if(errorCode != ALL_OK && errorCode != MOSTLY_OK)

    Unles ALL_OK == MOSTLY_OK, this is always false.

  • (cs) in reply to Anon.
    Anon.:
    > if(errorCode != ALL_OK && errorCode != MOSTLY_OK)

    Unles ALL_OK == MOSTLY_OK, this is always false.

    I see you're using non-DeMorgan booleans in that version of C you've been learning (assuming conventional precedence). They're a bit unusual… as in I have no idea what compiler would work that way. Which one is it (so we can stick to systems that use conventional semantics)?

  • Someone (unregistered) in reply to Anon.
    Anon.:
    > if(errorCode != ALL_OK && errorCode != MOSTLY_OK)

    Unles ALL_OK == MOSTLY_OK, this is always false.

    I realised afterward that i had meant '==' for all of the '!=' (that is, we only ever keep going when things are ok)

    The point remains that sometimes maintaing a single exit point seems a very clumsy way of doing things. especially since at the end we probably simply

    return errorCode; 
    

    Is the potential for mistakes in the 'if's somehow safer than the potential for mistakes in immediately returning errors? I would think that returning immediately is a good thing because it guarantees that no further execution of the function takes place. Nonetheless, I take the point that in very convoluted code it can be difficult to see whether every condition is covered - not sure if continued testing for an error condition makes the code any less convoluted, though.

  • Someone (unregistered) in reply to Someone
    Someone:
    Anon.:
    > if(errorCode != ALL_OK && errorCode != MOSTLY_OK)

    Unles ALL_OK == MOSTLY_OK, this is always false.

    I realised afterward that i had meant '==' for all of the '!=' (that is, we only ever keep going when things are ok)

    The point remains that sometimes maintaing a single exit point seems a very clumsy way of doing things. especially since at the end we probably simply

    return errorCode; 
    

    Is the potential for mistakes in the 'if's somehow safer than the potential for mistakes in immediately returning errors? I would think that returning immediately is a good thing because it guarantees that no further execution of the function takes place. Nonetheless, I take the point that in very convoluted code it can be difficult to see whether every condition is covered - not sure if continued testing for an error condition makes the code any less convoluted, though.

    And using == would make that && into an ||

    oops - next time I'll think first

  • Jo (unregistered) in reply to Anon.
    Anon.:
    > if(errorCode != ALL_OK && errorCode != MOSTLY_OK)

    Unles ALL_OK == MOSTLY_OK, this is always false.

    How so? What if errorCode = FRED. FRED != ALL_OK && FRED != MOSTLY_OK true && true true

    != (and ==) have a higher precedence than && (and ||) and will be evaluated first (or at least they do in c) http://www.difranco.net/cop2220/op-prec.htm

  • Hatterson (unregistered) in reply to Anguirel
    Anguirel:
    Pamela:
    Can someone explain to me what this is about, and where these date ranges are coming from? My VB6 knowledge is about as good as this code.

    Using the December 5 - January 25 one as an example:

    December 5 is 12/5 January 25 is 1/25

    The way it's storing the dates, they'll both end up as the string "<year>125_log.txt". Of course this is a bit of an assumption on my part since I've never actually used the VB date functions in question.

    Yea the VB6 works like this. Month() and Day() return non-padded/constant width values. 1-31 and 1-12 rather than the usually more preferred 01-21 and 01-12.

  • Hatterson (unregistered) in reply to Someone
    Someone:
    lolwtf:
    I like the "goto EndSub" instead of "exit sub".

    I want to blame the infinite loop on someone who was copying and pasting that code into everything without paying attention. Given their brillant commenting though, I somehow doubt this.

    Some people are taught that functions should only have one exit point, so they use techniques as the above. In some languages where 'goto' is discouraged these programmers (I might be using the term loosely in some cases) will have a flag on whether an error has occurred and check that every step of the way....

    I have seen lots of

    errorCode = doSomething(someParameters);
    if(errorCode != ALL_OK)
    {
      errorCorde = doSomethingElse(otherParamters);
    }
    if(errorCode != ALL_OK)
    {
      errorCode = tryThisFunction();
    }
    if(errorCode != ALL_OK && errorCode != MOSTLY_OK)
    {
      errorCode = whatAboutThis();
    }
    

    ....etc.... }

    I feel sorry for the person that values one exit point above not using gotos. Or rather I feel sorry for the person who has to come after them.

    Using goto in VB6 as a try/catch is acceptable, other than that I despise gotos

  • (cs)

    I wrote a HMI for a machine using Visual Basic .NET 2005. It was essentially just a front end to tell a provided DLL file to send a few commands to a motion controller.

    I found VB .NET's editor was quite good at auto-indenting and whatnot, and debugging was nice and simple. The client has had zero complaints with the application (which, incidentally, does error logging as well, but not of Windows errors. The log came in handy one day when the client called us and said "the machine broke! I think your motion controller program did it!" and I looked in the log and it said "Motion halted due to safety limits. User chose to override. Motion halted due to overtorque. User chose to override." and then the last datestamp was about half an hour before they called...)

    It doesn't hurt we have about 50x as much computing power as we need for the application (it's got a Celeron 600). The only real stupidity was having to create a second thread to run an update function so the GUI didn't freeze up when it was waiting for a reply from the motion controller - it's not really clear to me why VB doesn't do this on its own, as it would greatly simplify rapid prototyping of GUIs and whatnot. But then I just used a built-in helper class and all was well.

    One day I looked at some old VB6 code to see how a particular control setup was accomplished.

    Bahahahahaha.

    I'm never, ever touching VB6 unless I am truly as desperate as this guy's company seems to be.

  • Stiggy (unregistered)

    I've seen far worse.

    Race conditions rarely occur in classic VB(A), simply because it's damn near impossible to thread anything.

    The recursion bug is a facepalm, but it's one I've seen countless times before in VB.

    As for the comment indentation, yeah it's annoying. But I'd rather have a VB newbie try to explain what the hell they were thinking, in any indentation level, than not.

  • Stiggy (unregistered)

    I missed something. Hard-coding #1 as a file handle is just plain dumb. VB allocated file handles internally, so only the first file you opened would be #1. Many newbies didn't understand the nuance.

    The built-in FreeFile() function would return the next available handle.

  • Desperately Anonymous (unregistered) in reply to Anonymous
    Anonymous:
    Here is the painting of a landscape. But the artist who painted that picture says "something is missing; what is it? It is I myself who was a part of the landscape I painted". So he mentally takes a step backward, or 'regresses', and paints a picture of the artist painting a picture of the landscape.
    <snipped rest of quote>

    Okay, I know this is from a movie or TV episode.

    I even remember seeing it - with the camera pulling out, revealing ever more painters on the right-hand side of the canvas...

    But where is it from ?

    For some reason, I'm thinking an episode of "UFO" - "Close Up"...

  • MRAB (unregistered) in reply to Mad Formatter
    Mad Formatter:
    But you don't understand. It is company policy that all errors are logged!

    Hey at least they got the date elements in the right order*:

    CStr(Year(Now)) & CStr(Month(Now)) & CStr(Day(Now))

    Oops, never mind:

    Format(Date, "mm/dd/yyyy")

    P.S. TDWTF is WTF'd again today...

    There's also another potential problem: 'Now' could return different dates if it's used multiple times just as midnight arrives. However, that's the least of the problems...

    Captcha: vulputate. I'm sure that's illegal in some parts of the US.

  • (cs)

    Rimmer: Was there any damage? Holly: I don't know. The damage report machine has been damaged.

  • Hamachisn't (unregistered)

    Is everyone so hung up (pun not intended) on the recursion and possible races that they didn't see the missing endif? Of course they didn't see it; it's missing!

        'If the Log File exists then
                If FileExists(strPathAndFileName) Then        ' Where is this guy's endif?
            
        'Append to the end of the file - open for append
                    Open strPathAndFileName For Append As #1
                Else
            
        'Otherwise open a new file and add the new message - Open for output
                    Open strPathAndFileName For Output As #1
                                                                                        ' It probably belongs here.
        'End if system log file exists
                End If
    

    Just my $0.02let --H

    By the way... I once worked on Z80 code written by someone that was entirely devoid of comments except for the one repeating comment in places:

        mv      A,$20   ; move spase (sic)
    
  • The_Assimilator (unregistered)

    This is a classic WTF in that the first time you look at it, it actually looks like decent code... until you get to the error handling. Then you back and read over it again and notice the other WTF-ery like the ambiguous filenames and super-thread-unsafety.

    I can only think (hope?) that the original programmer was intending to write to the Windows error log in that error-handling block, but had a minor aneurysm while attempting to doing the implementation.

    Hopefully Matt made it his first priority to fix the logging routine!

  • katastrofa (unregistered)

    Well, at least they had logging. I've seen business-critical code which did not bother to log anything at all.

  • Lars P. (unregistered)

    Anybody got the obvious WTF of just using #1 file number for the open statement, instead of calling FreeFile to get a free number? If #1 was used by the function calling LogEntry an "Invalid File Number" like error would pop up, causing LogEntry to go into infinite regression right there, great!

    But the concept of building your own logging and tracing facilities, if you have to, is not a WTF at all.

  • Lars P. (unregistered) in reply to Stiggy
    I missed something. Hard-coding #1 as a file handle is just plain dumb. VB allocated file handles internally, so only the first file you opened would be #1. Many newbies didn't understand the nuance.
    Well, not exactly. You can use #1 as much as you want, but only for one file at the time. Using only #1 in the entire program is a very common sight in VB6, and it works fine as long as only one file is open at the time.

    But, using FreeFile is of course good practice and the way to go when dealing with multiple files. VB6 is supposed to be easy. Well it is at the beginning, but writing large, robust application in VB6 is a subtle art...

  • Ikke (unregistered) in reply to Anonymous
    Anonymous:
    Here is the painting of a landscape. But the artist who painted that picture says "something is missing; what is it? It is I myself who was a part of the landscape I painted". So he mentally takes a step backward, or 'regresses', and paints a picture of the artist painting a picture of the landscape. And still something is missing. That something is still his real self painting the second picture. So he 'regresses' further and paints a third, a picture of the artist painting a picture of the artist painting a picture of the landscape. And because something is still missing, he paints a fourth and fifth picture... so, infinite regression is the moment when our artist, having regressed to the point of infinity, himself becomes a part of the picture he has painted and is both the observer and the observed.
    What you describe is the Droste effect: http://en.wikipedia.org/wiki/Droste_effect ("Let's put an image of the box on the box")

    About your lanes into the future, a wise doctor once said: "People assume that time is a strict progression of cause to effect... but actually, from a non-linear, non-subjective viewpoint, it is more like a big ball of wibbly-wobbly... timey-wimey... stuff."

  • (cs) in reply to Lars P.
    Lars P.:
    ... But the concept of building your own logging and tracing facilities, if you have to, is not a WTF at all.
    But it is! There are plenty of decent libraries out there that have solved these problem reliably.

    And for all you .NET developers out there: there is no excuse for not use Enterprise Library for these kind of things (logging, caching, data access, IOC...)

  • Addison (unregistered)

    Alex, you don't expect us to actually READ that code, do you?

  • SR (unregistered) in reply to MC
    MC:
    Oh, no! The error logger experienced an error! I'd better report this to the error logger.

    That reminds me of Apache's "Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request."

    Admittedly it's well-handled but it always makes me smile when I see it.

  • tragomaskhalos (unregistered)

    I love this bit: 'Check that System Logging is enabled If Form1.chkLogEnabled.Value = 1 Then

    Scraping the UI for a global configuration parameter, and can't be arsed to rename the form from its default value - double score.

  • (cs) in reply to Kludge
    Kludge:
    In programs/scripts where every line is not commented, it is actually not always that difficult to follow the code.

    I agree, especially with syntax-based color highlighting.

  • (cs)

    What's the complaint? The code is heavily commented!!

    What drives me nuts with VB it is intolerant of my habit (from working with a dozen 'normal' languages) of terminating every line with a semicolon. It wouldn't be so bad if VB simply accepted semicolons as another delimiter.

  • Anonymous Coward (unregistered)

    Ah... the person who wrote that code didn't read 'Growing Better Software' (page 189).

  • Observer (unregistered) in reply to Ikke
    Ikke:
    Anonymous:
    Here is the painting of a landscape. But the artist who painted that picture says "something is missing; what is it? It is I myself who was a part of the landscape I painted". So he mentally takes a step backward, or 'regresses', and paints a picture of the artist painting a picture of the landscape. And still something is missing. That something is still his real self painting the second picture. So he 'regresses' further and paints a third, a picture of the artist painting a picture of the artist painting a picture of the landscape. And because something is still missing, he paints a fourth and fifth picture... so, infinite regression is the moment when our artist, having regressed to the point of infinity, himself becomes a part of the picture he has painted and is both the observer and the observed.
    What you describe is the Droste effect: http://en.wikipedia.org/wiki/Droste_effect ("Let's put an image of the box on the box")

    About your lanes into the future, a wise doctor once said: "People assume that time is a strict progression of cause to effect... but actually, from a non-linear, non-subjective viewpoint, it is more like a big ball of wibbly-wobbly... timey-wimey... stuff."

    So do you people replying to this actually think the OP came up with this? It's a quote from Escape From the Planet of the Apes dealing with the concept of Infinite Recursion...

  • (cs) in reply to Desperately Anonymous
    Desperately Anonymous:
    Anonymous:
    Here is the painting of a landscape. But the artist who painted that picture says "something is missing; what is it? It is I myself who was a part of the landscape I painted". So he mentally takes a step backward, or 'regresses', and paints a picture of the artist painting a picture of the landscape.
    <snipped rest of quote>

    Okay, I know this is from a movie or TV episode.

    I even remember seeing it - with the camera pulling out, revealing ever more painters on the right-hand side of the canvas...

    But where is it from ?

    For some reason, I'm thinking an episode of "UFO" - "Close Up"...

    Reminds me of Umma Gumma.

    [image]
  • Fedaykin (unregistered)

    Comments explaining trivial operations = EPIC WTF.

  • (cs)

    You mean VB doesn't have a built-in logging facility? (Quick search yields a resounding "no".)

  • Desperately Anonymous (unregistered) in reply to Observer
    Observer:
    <snipped quotation of script>

    So do you people replying to this actually think the OP came up with this? It's a quote from Escape From the Planet of the Apes dealing with the concept of Infinite Recursion...

    "Escape From The Planet Of The Apes" - that's it, I knew I'd seen it played out on the TV screen...

    ( curious that I was thinking it was from an episode of "UFO" though... )

  • sprezzatura (unregistered) in reply to Honky

    Actually, time does not exist. All that exists is the movement of matter. We measure all time by movement (clocks, electronic circuits). Time is an illusion, a convention.

  • Anonymous (unregistered)

    Call me crazy, but this doesn't look that bad to me. Sure it has the recursion bug, but hell:

    • It's commented.
    • It's indented.
    • It actually DOES logging.
    • And by the looks of it that's a structure that's going to be standard across all the routines (structure = good).
  • REM (unregistered) in reply to Javier
    Javier:
    And be thankful you have comments!.

    Code commenting is like sex - when it's good, it's very very good; but even when it's bad it is better than nothing.

  • Jon (unregistered) in reply to Hatterson

    I'm no VB6 user, so I may be mistaken, but I'm pretty sure that Format(Date, "mm/dd/yyyy") means the dates are in fact padded on output. They're padded in a stupid way, but they are padded.

Leave a comment on “Desperate Times”

Log In or post as a guest

Replying to comment #:

« Return to Article