Getting Rid of the “handler.call: handler undefined” Error

If you're using prototype (or rails, which uses prototype by default), you've probably seen this javascript error before:

handler is undefined

While not particularly threatening (no ill side effects seem to occur), the error causes a lot of noise and, quite frankly, is pretty annoying. Fortunately, there is a quick and painless patch to keep your error log free from this bane.


The problem occurs in the Event class defined by prototype. In the function createWrapper, there is a single line that causes the error.

handler.call(element, event);

The problem seems to be intermittent, but I get it fairly reliably when observing the "dom:loaded" event to automatically focus a text field on a page. I also see it reliably when observing the "load" event on a window to do the same thing. This leads me to believe there may be something going on with event handling at that level (although, this is just speculation).

In order to prevent this error we can use the old "undefined" trick to guard the line. While using a try block would work, that has the possibility for hiding all exceptions-- even the "valid" ones. For this reason I don't recommend using a try block. It should also be noted that trying to guard the line with a simple if (handler) does not work.

if (typeof handler != 'undefined') {
    handler.call(element, event);
}

This will prevent the error from occurring and not negatively affect the code in the process. While it doesn't technically fix the root cause of the issue (why is the handler undefined?), it will at least prevent your site from causing errors on every page.

The complete function looks like this:

function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (!Event || !Event.extend ||
        (event.eventName && event.eventName != eventName))
          return false;

      Event.extend(event);
      if (typeof handler != 'undefined') {
          handler.call(element, event);
      }
    };

Related posts:

  1. Remove/Cancel Bubbling for an Event in Flex3
  2. Breaking Prototype habits in a jQuery world
  3. Javascript debugging and testing in the wild (Prototype bug when using array.flatten in IE)
  4. Scriptaculous: Fixing Hover After Highlight
  5. Scriptaculous Drag and Drop with AJAX Update Fix for IE

Comments: 9 so far

  1. Thank you! This indeed prevents the ‘handler is undefined’ error from showing up. I use Prototype a lot to observe dom:loaded and never understood where this error came from.

    Comment by Sander, Tuesday, January 27, 2009 @ 5:46 pm

  2. Thanxs a lot – it helped! ;-)

    Comment by BugFix, Sunday, February 8, 2009 @ 12:27 am

  3. thanks for info :) my first thought was it is me doing something wrong with prototype Event.observe :)

    Comment by Quleczka, Sunday, March 1, 2009 @ 7:05 am

  4. Thanks for the solution.
    It takes care of error.

    Comment by Srikant, Friday, March 6, 2009 @ 12:49 pm

  5. Thank you for publishing this fix , I’m glad you were as annoyed as I was with this error

    Comment by Tyche, Saturday, March 7, 2009 @ 10:19 am

  6. The problem arises when the handler parameter to Event.observe is undefined. The likely cause of your error is the following.

    // Wrong. Passing result of callback function.
    Event.observe(window, “load”, the_callback());

    In the example above, the_callback() is being executed as you are making the Event.observe() call. That means the _result_ of the_callback() is being passed as the “handler” parameter of Event.observe().

    // Correct. Passing name of callback function.
    Event.observe(window, “load”, the_callback);

    In this case, you are passing the _name_ of the function to the “handler” parameter of Event.observe().

    Comment by Daniel Convissor, Tuesday, March 10, 2009 @ 10:22 am

  7. Hi Daniel Convissor.
    And if the calback function needs a parameter to be executed?
    How can I pass this parameter to the calback or in this case it’s not necessary?

    Comment by Bruno Lacerda, Tuesday, June 9, 2009 @ 6:03 am

  8. I have the same question. How can I pass a parameter to the callback function? If i do, the handler becomes undefined.

    Thanks in advance!

    Comment by juanjo, Monday, July 6, 2009 @ 4:15 am

  9. document.observe(’dom:loaded’, function(){test(’hi’)});

    Seems to work ok when parameters are needed in the callback

    Comment by Pums, Saturday, July 11, 2009 @ 4:09 am

Leave a comment

Powered by WP Hashcash

Launch: Pathfinder Newsletter

    Get a monthly update on best practices for delivering successful software.

    Subscribe via email


    Subscribe via RSS      RSS icon

Topics

Search

WordPress

Comments about this site: info@pathf.com