Internally, Movable Type is just a bunch of object oriented perl scripts. This means that almost everything in Movable Type, from entries to users to blogs is represented as "objects". Never mind the details of what that means exactly if you are not a programmer. But in order to load an object its information has to be pulled from the database first. This happens by calling the 'load' method for that particular type of object.
For example, you might see this bit of perl code somewhere in Movable Type:
my $entry = MT::Entry->load(53);
This will load all information about entry number 53 and turns the variable $entry into an object representing that entry. Further down in the code all sorts of interesthing things can then be done with the entry by calling methods on it:
$entry->title("A new title");
$entry->save;
This will set the title of the entry (using the "title" method) and then save it to the database (using the "save" method).
Still with me so far?
OK, now let's have a look at what can go wrong. Suppose there are only ten entries in your system, and the same line of code is executed:
my $entry = MT::Entry->load(53);
What happens now? You might expect an error to appear somewhere, because entry 53 does not exist. But that is not what happens. The "load" method just fails silently, and the variable $entry remains just that: an empty variable. Supposing the rest of the code is also executed like before, what do you suppose happens when we get to this line:
$entry->title("A new title");
Give yourself a point if you guessed that an error would appear saying: Can't call method "title" on an undefined value at... Indeed, $entry is just a variable at this point, and variables don't have methods that can be called on them. And it is also obvious that the error message gives you little or no insight as to what is really happening. The real issue is that entry 53 does not exist, which has nothing to do with the "title" method or the line number.
So how do you go about finding out the "real" error? Start by looking at the line number where the error occurs. Normally you should see the method that was mentioned being used on some variable, something like this:
$variable->method(...);
Now look up a few lines (or many lines) until you see the line where $variable was supposed to have been set to some object:
$variable = MT::Something->load(...);
Usually you will find a clue there about what MT was trying to load and this might help in figuring out what is really going on. Perhaps one of your database tables is corrupt? Or maybe a plugin is trying to load non-existent data? Or some cached data is still pointing to an object that no longer exists in the database?
A final note: you might be wondering why the "load" method to load most objects doesn't complain if no data can be found. This is by design, because sometimes you would expect the "load" method to come up with nothing (load all users with permission x, for example). In those cases the rest of the code should act accordingly, so the appropriate message can be displayed for example ("No users with permission x found"). Unfortunately, in many places in the code the possibility of "load" failing is not taken into consideration, resulting in weird error messages later if it does actually happen.
For example, you might see this bit of perl code somewhere in Movable Type:
my $entry = MT::Entry->load(53);
This will load all information about entry number 53 and turns the variable $entry into an object representing that entry. Further down in the code all sorts of interesthing things can then be done with the entry by calling methods on it:
$entry->title("A new title");
$entry->save;
This will set the title of the entry (using the "title" method) and then save it to the database (using the "save" method).
Still with me so far?
OK, now let's have a look at what can go wrong. Suppose there are only ten entries in your system, and the same line of code is executed:
my $entry = MT::Entry->load(53);
What happens now? You might expect an error to appear somewhere, because entry 53 does not exist. But that is not what happens. The "load" method just fails silently, and the variable $entry remains just that: an empty variable. Supposing the rest of the code is also executed like before, what do you suppose happens when we get to this line:
$entry->title("A new title");
Give yourself a point if you guessed that an error would appear saying: Can't call method "title" on an undefined value at... Indeed, $entry is just a variable at this point, and variables don't have methods that can be called on them. And it is also obvious that the error message gives you little or no insight as to what is really happening. The real issue is that entry 53 does not exist, which has nothing to do with the "title" method or the line number.
So how do you go about finding out the "real" error? Start by looking at the line number where the error occurs. Normally you should see the method that was mentioned being used on some variable, something like this:
$variable->method(...);
Now look up a few lines (or many lines) until you see the line where $variable was supposed to have been set to some object:
$variable = MT::Something->load(...);
Usually you will find a clue there about what MT was trying to load and this might help in figuring out what is really going on. Perhaps one of your database tables is corrupt? Or maybe a plugin is trying to load non-existent data? Or some cached data is still pointing to an object that no longer exists in the database?
A final note: you might be wondering why the "load" method to load most objects doesn't complain if no data can be found. This is by design, because sometimes you would expect the "load" method to come up with nothing (load all users with permission x, for example). In those cases the rest of the code should act accordingly, so the appropriate message can be displayed for example ("No users with permission x found"). Unfortunately, in many places in the code the possibility of "load" failing is not taken into consideration, resulting in weird error messages later if it does actually happen.


Leave a comment