Showing posts with label exceptions. Show all posts
Showing posts with label exceptions. Show all posts

Thursday, July 31, 2008

Why would my program suddenly stop working?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_would_my_program_suddenly_stop_working.htm]

Deterministic bugs are easy. When you write "ConvertCelsiusToFahrenheit", the debugging is simple. When things break, they're very repeatable, and it's easy to step through the debugger and see why. However, production code doesn't work this way. Sometimes your enterprise application will just temporarily stop working, only to resume working correctly again a little later. Why? Here's a few ideas:

  • Caching - something was cached, and the cache expired.

  • Session - the session expired

  • External dependencies - a dependent web service or database could be down

  • Rare boundary condition - perhaps your code doesn't account for certain rare input (like nulls, or not escaping special characters)

  • Concurrency - perhaps the code works great in a single thread (which is how must code is tested), but doesn't handle being run concurrently, for example one thread deadlocks, or another process locks a resource.

  • Too much load - perhaps too much load temporarily crashed something - like throwing an out of memory exception.

  • Randomness - maybe your code uses random numbers, and most of those work, but some of them don't - i.e. the code crashes when the random number is divisible by 111, or something really weird like that.

  • Incremental buildup with rounding error - perhaps every time the code is run, it produces an incremental buildup somewhere, like inserting a row in a database table. And as long as there are less than X rows, it "rounds down" and works. However, once the table has X+1 rows, it "rounds up" and something fails. This is abnormal, but certainly possible.

There is almost always some sufficient cause that causes the code to act abnormally. It helps for your app to have a good logger, such that you have clues to track down what that cause was. It also helps to have a QA environment that matches production, so that you can try to reproduce the steps yourself. Knowing that there will inevitably be production errors, it should encourage us to write good code upfront such that we take care of all the easy errors and these preventable bugs don't distract us from fixing the non-trivial ones.

Thursday, January 10, 2008

Missing EventValidation because modal dialogue blocked rendering

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/missing_eventvalidation_because_modal_dialogue_blocked_rende.htm]



I saw an application giving this error:
System.ArgumentException: Invalid postback or callback argument. Event validation is enabled using in configuration or in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
As is often the case, it "worked on my machine", but failed in production. It looked like one of those ghost bug things.
In this case, the problem was that the "EventValidation" field was missing entirely, so ASP.Net thought the page was corrupted:
  1. In production and QA, the page had a modal dialogue pop up. This was because both those environments ran in HTTPS, and that particular page had a JavaApplet on it, such that a modal dialogue popped up asking the user to confirm the security permissions.
  2. If the user clicked no, then that interfered with the final rendering at the bottom of  the page, which practically meant that just the "__EVENTVALIDATION" was never generated. The rest of the page looked the same.
  3. EventValidation was required to validate ViewState, so the server thought someone was hacking the page, and the Exception got thrown.
At first glance, a developer might just set Page EnableEventValidation="false", but that is a bad idea because it opens up a security hole (anyone could change your EventValidation value and exploit the app).
You can get an idea with this html code snippet, where I've substituted the JavaApplet call with an alert message (although the alert is truly modal, so you can't click a button until it's closed).
<body>
    <form id="form1" runat="server">
    <div>
   
  Text 1: this is the initial alert
   
  <script language="javascript" type="text/javascript">
    alert('yo!');
  </script>
 
  Text 2: this appears after the alert
 
    </div>
    </form>
</body
>
If you attach a debugger to the JS, you'll see that the second chunk of HTML text (Text 2) only gets rendered once the user closes the modal alert box. However, we can fix this by running the JavaScript code that called the applet in an asynch process via setTimeout, something like so:

<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript" language="javascript">

    function DoStuff()
    {
      setTimeout("MyMethod()",500);
    }
    function MyMethod() {
       alert('yo!');
    }

    </script>   
</head>
<body>
    <form id="form1" runat="server" >
    <div>
    ASYNCH Hello world
   
    this is the initial code
   
  <script language="javascript" type="text/javascript">
    DoStuff()
  </script>
 
  this appears after the code
 
    </div>
    </form>
</body>
</html
>