View RSS Feed

Development Team Blog

Sometimes it's better to Just do it

Rate this Entry
I very often see questions like "How can I find out if doing xyz will work?". Often that's in disguise for a more straightforward problem like "Sometimes when I do xyz I get an error, I just want to suppress the error and do something else instead."

That original problem should lead you to think: "I know, I'll check for the error and handle it". But all too often it turns into "I'll figure out if doing xyz is going to succeed first, and then I do xyz, hoping I was right". That's almost always going to make the problem worse by turning one problem into two new problems instead of really solving anything.

Why is that just making it worse? Because there are two ways such a test can go wrong. When you try to find out, you may get a false positive, and then when you actually perform the operation it fails anyway, so you're right back to the original problem. And worse, sometimes you may get a false negative, so you decide not to go ahead, even though it really would have succeeded, which leads to frustrated users because they can't get past your test. And of course, if this is a performance critical piece of code, any test is going to add overhead so it can be a performance issue as well.

The solution is of course like Nike says, Just do it, intercept any potential error and abort the operation if it failed. This is really the best of all. In most cases the operation will just work, in which case there's basically no overhead at all. There is never any potential for false positives or false negatives since there's no expensive test, you just do it. If it fails, it really did fail, there's no question about it.

It's super easy to do as well.

Code:
Send Ignore_Error to Error_Object_Id 54
Move False to Err
Move "12,49,125,125" to nVal //Could raise error
Move Err to bErr
Send Trap_Error to Error_Object_Id 54
If (bErr) Begin
    Showln "An error occurred"
End
In many cases it's by definition impossible to test for the error beforehand, and the only solution is to just do it and see if it worked afterwards. For example, opening or locking files. If you test for the condition at first and then perform the operation, someone or something else can cause it to change inbetween your test and the operation. It's much better to Just do it, and then see if it worked. If it failed, you could then do some further tests to try and narrow it down. But the important thing is to do such tests after it already has failed, and only in an attempt to narrow down the cause of failure and/or potential solutions.

If the operation is significantly more complex than the above example, you can get fancy and create your own error handler object instead.

Comments

  1. Peter Miska's Avatar
    Sonny,

    I've used custom error handlers to avoid repetitive code. For example. The Mertech errors are 25000, but you can get more information. By writing a custom handler not only do I trap the error but I roll back the transaction as well, create an xsl transformation and exit the program gracefully.
  2. Karl's Avatar
    Please implement TRY/CATCH, then your code could be like this (in my opinion far better):

    Code:
    Try
      Move "12,49,125,125" to nVal //Could raise error
    Catch (E:Exception)
      If (E.ErrNum = 54) Showln "An error 54 occurred"
      Else               Showln "Anoter error occurred"
    End
  3. seanyboy's Avatar
    Here's another vote for try/catch.
  4. Anders Ohrt's Avatar
    It shouldn't be too hard to create a try/catch macro, I think... Actually, I went ahead and implemented it, see the Open Source forum.
    Updated 1-Feb-2010 at 02:13 PM by Anders Ohrt
  5. erikzcai's Avatar
    Nevermind
    Updated 16-Feb-2010 at 12:56 PM by erikzcai